﻿#include "taskmanagerserver.h"


taskManagerServer::taskManagerServer(QObject *parent) : QObject(parent)
{

    qRegisterMetaType<QMap<int,CodeStatus>>("QMap<int,CodeStatus>");
    qRegisterMetaType<QMap<QString,AGVCurrentTask>>("QMap<QString,AGVCurrentTask>");

    taskManagerServerInit();

    StTimer = new QTimer(this);
    connect(StTimer,&QTimer::timeout,this,&taskManagerServer::taskManagerServerTimer);
    StTimer->start(300);

    StTimer_ = new QTimer(this);
    connect(StTimer_,&QTimer::timeout,this,&taskManagerServer::taskManagerServerTimer_);
    StTimer_->start(1000);

    // 逻辑定时器
    StTimer_CR3 = new QTimer(this);
    connect(StTimer_CR3,&QTimer::timeout,this,&taskManagerServer::taskManagerServerTimer_CR3);
    StTimer_CR3->start(300);

}

void taskManagerServer::taskManagerServerInit()
{

    ThreadInsertI=new ThreadInsert;
    ThreadInsertItiem=new QThread();
    ThreadInsertI->moveToThread(ThreadInsertItiem);
    ThreadInsertItiem->start();

    threadQueryI=new threadQuery;
    threadQueryItem=new QThread();
    threadQueryI->moveToThread(threadQueryItem);
    threadQueryItem->start();

    /***************** 广州蔡司CR开模3线 *******************/
    ModbusManageI = new ModbusManage;
    ModbusManageItem = new QThread();
    threadQueryI->moveToThread(threadQueryItem);
    ModbusManageItem->start();

    // 指定Modbus线圈写入指定值
    connect(this, &taskManagerServer::sig_MoubusWriteCoil_QR, ModbusManageI, &ModbusManage::ON_MoubusWriteCoil_QR);
    connect(this, &taskManagerServer::sig_MoubusWriteCoil_QC, ModbusManageI, &ModbusManage::ON_MoubusWriteCoil_QC);
    connect(this, &taskManagerServer::sig_MoubusWriteCoil_RS, ModbusManageI, &ModbusManage::ON_MoubusWriteCoil_RS);
    connect(this, &taskManagerServer::sig_MoubusWriteCoil_RX, ModbusManageI, &ModbusManage::ON_MoubusWriteCoil_RX);
    connect(this, &taskManagerServer::sig_MoubusWriteCoil_Client, ModbusManageI, &ModbusManage::ON_MoubusWriteCoil_Client);

    //待机点站点号
//    StopStation.insert(1, 1);

    //PLC 线圈写入地址
    PLCWrite.insert("QR_Y10", 999);         // QR 信号

    PLCWrite.insert("QC_Y10", 1047);        // QC 信号

    PLCWrite.insert("RX_Y10", 1095);        // RX 信号
    PLCWrite.insert("RX_Y11", 1096);        // RX 信号

    PLCWrite.insert("RS_Y10", 1143);        // RS 信号
    PLCWrite.insert("RS_Y11", 1144);        // RS 信号

    // 对接工位等待站点写入
//    StationWrite.insert("WK", "WKW");         // 网格空料中转位
//    StationWrite.insert("WM", "WMW");         // 网格满料中转位

    //获取AGV状态 0：空闲 1：已分配任务
    AGVStationMap.insert(1, 0);
}

bool taskManagerServer::taskProcessTimer()
{
    // 当前任务列表
    QMap<int, SAPExcelInfo>::iterator iter=currentSAPExcelInfoTask.begin();
    while (iter!=currentSAPExcelInfoTask.end())
    {

        // 临时任务参数集合
        SAPExcelInfo SAPExcelInfoI;

        // 当前 AGV 状态信息
        AGVCurrentTask AGVCurrentTaskI;

        // AGV编号初始化
//        int AGVId = 0;

//        if(iter->agvNum == "0")
//        {
//            // 指定 AGV 空闲 1
//            AGVId = GetFreeAGV("1", "2", "");

//            if(AGVId == 1 || AGVId == 2)
//            {
//                // 当前 AGV 状态信息
//                AGVCurrentTaskI = AGVCurrentTaskMap.value(QString::number(AGVId));
//            }

//        }

        // 当前 AGV 状态信息
        AGVCurrentTaskI = AGVCurrentTaskMap.value(iter->agvNum);

        // 获取滚筒光栅状态
        bool X17 = ESS_Single::GetInstance()->getIOStatus(AGVCurrentTaskI.inputIOStatus, 17);// AGV 外中侧光栅传感器
        bool X18 = ESS_Single::GetInstance()->getIOStatus(AGVCurrentTaskI.inputIOStatus, 18);// AGV 内中侧光栅传感器
        bool X19 = ESS_Single::GetInstance()->getIOStatus(AGVCurrentTaskI.inputIOStatus, 19);// AGV 外侧光栅传感器
        bool X20 = ESS_Single::GetInstance()->getIOStatus(AGVCurrentTaskI.inputIOStatus, 20);// AGV 内侧光栅传感器

        // 获取滚筒转动状态
        bool Y11 = ESS_Single::GetInstance()->getIOStatus(AGVCurrentTaskI.outputIOStatus, 11);// AGV 滚筒电机使能状态
        bool Y12 = ESS_Single::GetInstance()->getIOStatus(AGVCurrentTaskI.outputIOStatus, 12);// AGV 滚筒电机方向状态

        /******************************************* 清洗流程 ****************************************/
        if (iter->taskType == "ONE"){

            // 闪退、下发RCS任务超时未响应处理
            if (iter->taskStatus == 1 || iter->taskStatus == 4
                     || iter->taskStatus == 6 || iter->taskStatus == 9)
            {
                if(ONE_Time.toString().isEmpty()){
                    ONE_Time = QDateTime::currentDateTime();
                }else
                {
                    if(ONE_Time.secsTo(QDateTime::currentDateTime()) > 10)
                    {
//                        if(iter->taskStatus == 1){
//                            AGVStationMap.insert(iter->agvNum.toInt(), 0);
//                            iter->agvNum = "";
//                        }
                        iter->taskStatus--;
                        ONE_Time = nullTime;
                        qDebug()<<"--------- Timeout Task Status Reset -------->taskId:"<<iter->taskId<<" taskStatus:"<<iter->taskStatus<<" SAPTaskIndex:"<<iter->SAPTaskIndex;
                    }
                }
            }

            // 0 等待 AGV 执行
            if (iter->taskStatus == 0){

                // 下发RCS移动任务，前往清洗入料工位1
                iter->taskId_ess = "Move-" + QString::number(iter->SAPTaskIndex) + "-1";

                // 上一条未放行任务
                iter->taskId_agv = iter->taskId_ess;

                ESS_Single::GetInstance()->setMoveTask(iter.value(), currentStationInfoMap.value(iter->load).currentStation, "MOVE", 0);

                iter->taskStatus++;

            }

            // 1 开始执行任务

            // 2 前往清洗入料 到达清洗入料工位
            if (iter->taskStatus == 2 && currentStationInfoMap.value(iter->load).Currentpoint == AGVCurrentTaskI.currentNode){

                iter->taskStatus++;

            }

            // 3 对接清洗入料 到达清洗入料工位
            if (iter->taskStatus == 3 && currentStationInfoMap.value(iter->load).Currentpoint == AGVCurrentTaskI.currentNode
                    && AGVCurrentTaskI.mCurrentTaskNum == 0){

                // 外、内侧无篮子
                if (!X17 && !X18 && !X19 && !X20)
                {
                    // 入料位X10=1与入料外部X13=1，入料位X10=0与入料外部X13=0
                    if ((PLC_Read(iter->load, "X13") && PLC_Read(iter->load, "X10")) || (!PLC_Read(iter->load, "X13") && !PLC_Read(iter->load, "X10")))
                    {
                        // 下发RCS移动任务，前往清洗出料工位4
                        iter->taskId_ess = "Move-" + QString::number(iter->SAPTaskIndex) + "-4";

                        ESS_Single::GetInstance()->setMoveTask(iter.value(), currentStationInfoMap.value(iter->unload).currentStation, "MOVE", 0);

                        iter->taskStatus++;
                    }

                    // 入料位X10=0与入料外部X13=1
                    else  if ((PLC_Read(iter->load, "X13") && !PLC_Read(iter->load, "X10")))
                    {
                        // 创建设置语音任务（篮子不到位提醒）
                        ESS_Single::GetInstance()->setAgvMusicTask(iter->agvNum.toInt(), 2);
                    }

                }

                // 入料位X10=0，滚筒状态X12=0，滚筒使能Y10=0
                else if (!PLC_Read(iter->load, "X10") && !PLC_Read(iter->load, "X12")
                         && !PLC_Read(iter->load, "Y10"))
                {
                    // 滚筒使能Y11置1
                    PLC_Write(iter->load, "QR_Y10", 1);

                }

                // 入料位X10=0，滚筒使能Y10=1，滚筒状态X12=1
                else if (!PLC_Read(iter->load, "X10") && PLC_Read(iter->load, "X12")
                         && PLC_Read(iter->load, "Y10"))
                {
                    // 滚筒使能Y11置0
                    PLC_Write(iter->load, "QR_Y10", 0);

                    // 外侧有篮子
                    if (X17 && iter->taskId_ess != "Action-" + QString::number(iter->SAPTaskIndex) + "-2")
                    {
                        // 下发RCS动作任务104，滚筒外侧送料2
                        iter->taskId_ess = "Action-" + QString::number(iter->SAPTaskIndex) + "-2";

                        // RCS动作任务
                        ESS_Single::GetInstance()->setActionTask(iter.value(), currentStationInfoMap.value(iter->load).currentStation, 104, "Action", 0);
                    }

                    // 外侧无篮子,内侧有蓝子
                    if (!X17 && X18 && !X19 && X20 && iter->taskId_ess != "Action-" + QString::number(iter->SAPTaskIndex) + "-3")
                    {
                        // 下发RCS动作任务102，滚筒内侧送料3
                        iter->taskId_ess = "Action-" + QString::number(iter->SAPTaskIndex) + "-3";

                        // RCS动作任务
                        ESS_Single::GetInstance()->setActionTask(iter.value(), currentStationInfoMap.value(iter->load).currentStation, 102, "Action", 0);
                    }

                }

            }

            // 4 清洗入料完成

            // 5 对接清洗出料 到达清洗出料工位
            if (iter->taskStatus == 5 && currentStationInfoMap.value(iter->unload).Currentpoint == AGVCurrentTaskI.currentNode){

                // 出料位X10=0,Y11=0,滚筒使能Y10=1,无动作
                if (!PLC_Read(iter->unload, "X10") && !Y11 && PLC_Read(iter->unload, "Y10")
                         && AGVCurrentTaskI.mCurrentTaskNum == 0)
                {
                    // 滚筒使能Y11置0
                    PLC_Write(iter->unload, "QC_Y10", 0);
                }

                // 出料位X10=1，Y11=1,有动作
                else if (PLC_Read(iter->unload, "X10") && Y11 && AGVCurrentTaskI.mCurrentTaskNum > 0)
                {
                    // 滚筒使能Y11置1
                    PLC_Write(iter->unload, "QC_Y10", 1);

                }

                // 内、外侧有篮子 || 出料位X10=0,出料平台X11=0,无动作
                else if (((X17 && X18 && X20) || (!PLC_Read(iter->unload, "X10") && !PLC_Read(iter->unload, "X11")))
                         && AGVCurrentTaskI.mCurrentTaskNum == 0)
                {

                    // 下发RCS移动任务，前往人工下料工位7
                    iter->taskId_ess = "Move-" + QString::number(iter->SAPTaskIndex) + "-7";

                    ESS_Single::GetInstance()->setMoveTask(iter.value(), currentStationInfoMap.value("RX").currentStation, "MOVE", 0);

                    iter->taskStatus++;
                }

                // 出料位X10=1，滚筒状态X12=0,滚筒使能Y10=0,Y11=0,无动作
                else if (PLC_Read(iter->unload, "X10") && !PLC_Read(iter->unload, "X12")
                        && !PLC_Read(iter->unload, "Y10") && !Y11 && AGVCurrentTaskI.mCurrentTaskNum == 0)
                {

                    // 内、外侧无篮子
                    if (!X17 && !X18 && !X19 && !X20 && iter->taskId_ess != "Action-" + QString::number(iter->SAPTaskIndex) + "-5")
                    {
                        // 下发RCS动作任务101，滚筒内侧取料5
                        iter->taskId_ess = "Action-" + QString::number(iter->SAPTaskIndex) + "-5";

                        // RCS动作任务
                        ESS_Single::GetInstance()->setActionTask(iter.value(), currentStationInfoMap.value(iter->unload).currentStation, 101, "Action", 0);

                    }

                    // 内侧有篮子,外侧无篮子
                    else if (!X17 && X18 && !X19 && X20 && iter->taskId_ess != "Action-" + QString::number(iter->SAPTaskIndex) + "-6")
                    {
                        // 下发RCS动作任务103，滚筒外侧取料6
                        iter->taskId_ess = "Action-" + QString::number(iter->SAPTaskIndex) + "-6";

                        // RCS动作任务
                        ESS_Single::GetInstance()->setActionTask(iter.value(), currentStationInfoMap.value(iter->unload).currentStation, 103, "Action", 0);
                    }

                }

            }

            // 6 清洗出料完成

            // 7 前往人工下料 到达人工下料工位
            if (iter->taskStatus == 7 && currentStationInfoMap.value("RX").Currentpoint == AGVCurrentTaskI.currentNode){

                iter->taskStatus++;

            }

            // 8 等待取篮放行 到达人工下料工位 内外侧无篮子
            if (iter->taskStatus == 8 && currentStationInfoMap.value("RX").Currentpoint == AGVCurrentTaskI.currentNode){

                // 有篮
                if (X17 || (X18 && X20))
                {
                    // 计时=0
                    if (Music_Time.toString().isEmpty())
                    {
                        Music_Time = QDateTime::currentDateTime();
                    }

                    // 超时30S，语音提醒
                    else if (Music_Time.secsTo(QDateTime::currentDateTime()) > 30)
                    {
                        // 创建设置语音任务（取篮广播提醒）
                        ESS_Single::GetInstance()->setAgvMusicTask(iter->agvNum.toInt(), 1);
                    }

                }

                // 空篮
                else if (!X17 && !X18 && !X19 && !X20)
                {
                    // 计时=0
                    if (OUT_Time.toString().isEmpty())
                    {
                        OUT_Time = QDateTime::currentDateTime();
                    }

                    // 黄色放行X12=1，黄色确认Y11=0
                    else if (PLC_Read("RX", "X12") && !PLC_Read("RX", "Y11"))
                    {
                        // 黄色确认Y11置1
                        PLC_Write("RX", "RX_Y11", 1);
                    }

                    // 黄色确认Y11=1||超时60S
                    else if (PLC_Read("RX", "Y11") || OUT_Time.secsTo(QDateTime::currentDateTime()) > 60)
                    {

                        // 计时情空
                        OUT_Time = nullTime;

                        Music_Time = nullTime;

                        // 下发RCS移动任务，前往清洗出料工位8
                        iter->taskId_ess = "Move-" + QString::number(iter->SAPTaskIndex) + "-8";

                        ESS_Single::GetInstance()->setMoveTask(iter.value(), currentStationInfoMap.value(iter->unload).currentStation, "MOVE", 0);

                        iter->taskStatus++;

                    }else
                    {
                        //提示文本描述显示
                        emit sig_TextDisplay(tr("%1 任务条件不满足--->OUT_Time：%2 X12：%3 Y11：%4").arg(iter->SAPTaskIndex).arg(OUT_Time.secsTo(QDateTime::currentDateTime()))
                                             .arg(PLC_Read("RX", "X12")).arg(PLC_Read("RX", "Y11")));

                        qDebug()<<"-----任务条件不满足---->taskId:"<<iter->taskId<<" OUT_Time:"<<OUT_Time.secsTo(QDateTime::currentDateTime())
                               <<" X12:"<<PLC_Read("RX", "X12")<<" Y11:"<<PLC_Read("RX", "Y11");
                    }

                }

            }

            // 9 取篮放行完成

            // 10 前往清洗出料 到达清洗出料工位
            if (iter->taskStatus == 10 && currentStationInfoMap.value(iter->unload).Currentpoint == AGVCurrentTaskI.currentNode){

                // 任务正常完成
                iter->taskStatus=100;

                iter->taskId_agv = iter->taskId_ess;

                // 放行RCS移动任务，前往清洗出料工位
                ESS_Single::GetInstance()->setRunActionTask(iter.value());

                // 复位 PLC 按钮盒信号
                StationStatus_Reset(iter.value());

            }

            // 防止任务完成更新状态失败
            if(iter->taskStatus == 10 && !X17 && !X18 && !X19 && !X20 && iter->taskId != AGVCurrentTaskI.taskId)
            {
                // 任务正常完成
                iter->taskStatus=100;
            }

        }

        /******************************************* 转运流程 ****************************************/
        if (iter->taskType == "TWO"){

            // 闪退、下发RCS任务超时未响应处理
            if (iter->taskStatus == 1 || iter->taskStatus == 4 || iter->taskStatus == 7)
            {
                if(TWO_Time.toString().isEmpty()){
                    TWO_Time = QDateTime::currentDateTime();
                }else
                {
                    if(TWO_Time.secsTo(QDateTime::currentDateTime()) > 10)
                    {
//                        if(iter->taskStatus == 1){
//                            AGVStationMap.insert(iter->agvNum.toInt(), 0);
//                            iter->agvNum = "";
//                        }
                        iter->taskStatus--;
                        TWO_Time = nullTime;
                        qDebug()<<"--------- Timeout Task Status Reset -------->taskId:"<<iter->taskId<<" taskStatus:"<<iter->taskStatus<<" SAPTaskIndex:"<<iter->SAPTaskIndex;
                    }
                }
            }

            // 0 等待 AGV 执行
            if (iter->taskStatus == 0){

                // 下发RCS移动任务，前往清洗出料工位1
                iter->taskId_ess = "Move-" + QString::number(iter->SAPTaskIndex) + "-1";

                // 上一条未放行任务
                iter->taskId_agv = iter->taskId_ess;

                ESS_Single::GetInstance()->setMoveTask(iter.value(), currentStationInfoMap.value("QC").currentStation, "MOVE", 0);

                iter->taskStatus++;

            }

            // 1 开始执行任务

            // 2 前往清洗出料 到达清洗出料工位
            if (iter->taskStatus == 2 && currentStationInfoMap.value("QC").Currentpoint == AGVCurrentTaskI.currentNode){

                iter->taskStatus++;

            }

            // 3 对接清洗出料 到达清洗出料工位
            if (iter->taskStatus == 3 && currentStationInfoMap.value("QC").Currentpoint == AGVCurrentTaskI.currentNode){

                // 出料位X10=0,Y11=0,滚筒使能Y10=1,无动作
                if (!PLC_Read("QC", "X10") && !Y11 && PLC_Read("QC", "Y10")
                         && AGVCurrentTaskI.mCurrentTaskNum == 0)
                {
                    // 滚筒使能Y11置0
                    PLC_Write("QC", "QC_Y10", 0);
                }

                // 出料位X10=1，Y11=1,有动作
                else if (PLC_Read("QC", "X10") && Y11 && AGVCurrentTaskI.mCurrentTaskNum > 0)
                {
                    // 滚筒使能Y11置1
                    PLC_Write("QC", "QC_Y10", 1);

                }

                // 内、外侧有篮子 || 出料位X10=0,出料平台X11=0,无动作
                else if (((X17 && X18 && X20) || (!PLC_Read("QC", "X10") && !PLC_Read("QC", "X11")))
                         && AGVCurrentTaskI.mCurrentTaskNum == 0)
                {

                    // 下发RCS移动任务，前往人工下料工位4
                    iter->taskId_ess = "Move-" + QString::number(iter->SAPTaskIndex) + "-4";

                    ESS_Single::GetInstance()->setMoveTask(iter.value(), currentStationInfoMap.value(iter->unload).currentStation, "MOVE", 0);

                    iter->taskStatus++;
                }

                // 出料位X10=1，滚筒状态X12=0,滚筒使能Y10=0,Y11=0,无动作
                else if (PLC_Read("QC", "X10") && !PLC_Read("QC", "X12")
                        && !PLC_Read("QC", "Y10") && !Y11 && AGVCurrentTaskI.mCurrentTaskNum == 0)
                {

                    // 内、外侧无篮子
                    if (!X17 && !X18 && !X19 && !X20 && iter->taskId_ess != "Action-" + QString::number(iter->SAPTaskIndex) + "-2")
                    {
                        // 下发RCS动作任务101，滚筒内侧取料2
                        iter->taskId_ess = "Action-" + QString::number(iter->SAPTaskIndex) + "-2";

                        // RCS动作任务
                        ESS_Single::GetInstance()->setActionTask(iter.value(), currentStationInfoMap.value("QC").currentStation, 101, "Action", 0);

                    }

                    // 内侧有篮子,外侧无篮子
                    else if (!X17 && X18 && !X19 && X20 && iter->taskId_ess != "Action-" + QString::number(iter->SAPTaskIndex) + "-3")
                    {
                        // 下发RCS动作任务103，滚筒外侧取料3
                        iter->taskId_ess = "Action-" + QString::number(iter->SAPTaskIndex) + "-3";

                        // RCS动作任务
                        ESS_Single::GetInstance()->setActionTask(iter.value(), currentStationInfoMap.value("QC").currentStation, 103, "Action", 0);
                    }

                }

            }

            // 4 清洗出料完成

            // 5 前往人工下料 到达人工下料工位
            if (iter->taskStatus == 5 && currentStationInfoMap.value(iter->unload).Currentpoint == AGVCurrentTaskI.currentNode){

                iter->taskStatus++;

            }

            // 6 等待取篮放行 到达人工下料工位 内外侧无篮子
            if (iter->taskStatus == 6 && currentStationInfoMap.value(iter->unload).Currentpoint == AGVCurrentTaskI.currentNode){

                // 有篮
                if (X17 || (X18 && X20))
                {
                    // 计时=0
                    if (Music_Time.toString().isEmpty())
                    {
                        Music_Time = QDateTime::currentDateTime();
                    }

                    // 超时30S，语音提醒
                    else if (Music_Time.secsTo(QDateTime::currentDateTime()) > 30)
                    {
                        // 创建设置语音任务（更换电池广播）
                        ESS_Single::GetInstance()->setAgvMusicTask(iter->agvNum.toInt(), 1);
                    }

                }

                // 空篮
                else if (!X17 && !X18 && !X19 && !X20)
                {
                    // 计时=0
                    if (OUT_Time.toString().isEmpty())
                    {
                        OUT_Time = QDateTime::currentDateTime();
                    }

                    // 黄色放行X12=1，黄色确认Y11=0
                    else if (PLC_Read(iter->unload, "X12") && !PLC_Read(iter->unload, "Y11"))
                    {
                        // 黄色确认Y11置1
                        PLC_Write(iter->unload, "RX_Y11", 1);
                    }

                    // 黄色确认Y11=1||超时60S
                    else if (PLC_Read(iter->unload, "Y11") || OUT_Time.secsTo(QDateTime::currentDateTime()) > 60)
                    {

                        // 计时情空
                        OUT_Time = nullTime;

                        Music_Time = nullTime;

                        // 下发RCS移动任务，前往清洗出料工位5
                        iter->taskId_ess = "Move-" + QString::number(iter->SAPTaskIndex) + "-5";

                        ESS_Single::GetInstance()->setMoveTask(iter.value(), currentStationInfoMap.value("QC").currentStation, "MOVE", 0);

                        iter->taskStatus++;

                    }else
                    {
                        //提示文本描述显示
                        emit sig_TextDisplay(tr("%1 任务条件不满足--->OUT_Time：%2 X12：%3 Y11：%4").arg(iter->SAPTaskIndex).arg(OUT_Time.secsTo(QDateTime::currentDateTime()))
                                             .arg(PLC_Read(iter->unload, "X12")).arg(PLC_Read(iter->unload, "Y11")));

                        qDebug()<<"-----任务条件不满足---->taskId:"<<iter->taskId<<" OUT_Time:"<<OUT_Time.secsTo(QDateTime::currentDateTime())
                               <<" X12:"<<PLC_Read(iter->unload, "X12")<<" Y11:"<<PLC_Read(iter->unload, "Y11");
                    }

                }

            }

            // 7 取篮放行完成

            // 8 前往清洗出料 到达清洗出料工位
            if (iter->taskStatus == 8 && currentStationInfoMap.value("QC").Currentpoint == AGVCurrentTaskI.currentNode){

                // 任务正常完成
                iter->taskStatus=100;

                iter->taskId_agv = iter->taskId_ess;

                // 放行RCS移动任务，前往清洗出料工位
                ESS_Single::GetInstance()->setRunActionTask(iter.value());

                // 复位 PLC 按钮盒信号
                StationStatus_Reset(iter.value());

            }

            // 防止任务完成更新状态失败
            if(iter->taskStatus == 8 && !X17 && !X18 && !X19 && !X20 && iter->taskId != AGVCurrentTaskI.taskId)
            {
                // 任务正常完成
                iter->taskStatus=100;
            }

        }

        /******************************************* 出篮流程 ****************************************/
        if (iter->taskType == "THREE"){

            // 闪退、下发RCS任务超时未响应处理
            if (iter->taskStatus == 2 || iter->taskStatus == 5)
            {
                if(THREE_Time.toString().isEmpty()){
                    THREE_Time = QDateTime::currentDateTime();
                }else
                {
                    if(THREE_Time.secsTo(QDateTime::currentDateTime()) > 10)
                    {
//                        if(iter->taskStatus == 1){
//                            AGVStationMap.insert(iter->agvNum.toInt(), 0);
//                            iter->agvNum = "";
//                        }
                        iter->taskStatus--;
                        THREE_Time = nullTime;
                        qDebug()<<"--------- Timeout Task Status Reset -------->taskId:"<<iter->taskId<<" taskStatus:"<<iter->taskStatus<<" SAPTaskIndex:"<<iter->SAPTaskIndex;
                    }
                }
            }

            // 0 等待 AGV 执行 到达清洗出料工位
            if (iter->taskStatus == 0 && currentStationInfoMap.value(iter->load).Currentpoint == AGVCurrentTaskI.currentNode){

                iter->taskStatus++;

            }

            // 1 对接清洗出料 到达清洗出料工位
            if (iter->taskStatus == 1 && currentStationInfoMap.value(iter->load).Currentpoint == AGVCurrentTaskI.currentNode){

                // 出料位X10=0,Y11=0,滚筒使能Y10=1,无动作
                if (!PLC_Read(iter->load, "X10") && !Y11 && PLC_Read(iter->load, "Y10")
                         && AGVCurrentTaskI.mCurrentTaskNum == 0)
                {
                    // 滚筒使能Y11置0
                    PLC_Write(iter->load, "QC_Y10", 0);
                }

                // 出料位X10=1，Y11=1,有动作
                else if (PLC_Read(iter->load, "X10") && Y11 && AGVCurrentTaskI.mCurrentTaskNum > 0)
                {
                    // 滚筒使能Y11置1
                    PLC_Write(iter->load, "QC_Y10", 1);

                }

                // 内、外侧有篮子 || 出料位X10=0,出料平台X11=0,无动作
                else if (((X17 && X18 && X20) || (!PLC_Read(iter->load, "X10") && !PLC_Read(iter->load, "X11")))
                         && AGVCurrentTaskI.mCurrentTaskNum == 0)
                {

                    // 下发RCS移动任务，前往人工下料工位3
                    iter->taskId_ess = "Move-" + QString::number(iter->SAPTaskIndex) + "-3";

                    ESS_Single::GetInstance()->setMoveTask(iter.value(), currentStationInfoMap.value(iter->unload).currentStation, "MOVE", 0);

                    iter->taskStatus++;
                }            

                // 出料位X10=1，滚筒状态X12=0,滚筒使能Y10=0,Y11=0,无动作
                else if (PLC_Read(iter->load, "X10") && !PLC_Read(iter->load, "X12")
                        && !PLC_Read(iter->load, "Y10") && !Y11 && AGVCurrentTaskI.mCurrentTaskNum == 0)
                {

                    // 内、外侧无篮子
                    if (!X17 && !X18 && !X19 && !X20 && iter->taskId_ess != "Action-" + QString::number(iter->SAPTaskIndex) + "-1")
                    {
                        // 下发RCS动作任务101，滚筒内侧取料1
                        iter->taskId_ess = "Action-" + QString::number(iter->SAPTaskIndex) + "-1";

                        // 上一条未放行任务
                        iter->taskId_agv = iter->taskId_ess;

                        // RCS动作任务
                        ESS_Single::GetInstance()->setActionTask(iter.value(), currentStationInfoMap.value(iter->load).currentStation, 101, "Action", 0);

                    }

                    // 内侧有篮子,外侧无篮子
                    else if (!X17 && X18 && !X19 && X20 && iter->taskId_ess != "Action-" + QString::number(iter->SAPTaskIndex) + "-2")
                    {
                        // 下发RCS动作任务103，滚筒外侧取料2
                        iter->taskId_ess = "Action-" + QString::number(iter->SAPTaskIndex) + "-2";

                        // RCS动作任务
                        ESS_Single::GetInstance()->setActionTask(iter.value(), currentStationInfoMap.value(iter->load).currentStation, 103, "Action", 0);
                    }

                }                           

            }

            // 2 清洗出料完成

            // 3 前往人工下料 到达人工下料工位
            if (iter->taskStatus == 3 && currentStationInfoMap.value(iter->unload).Currentpoint == AGVCurrentTaskI.currentNode){

                iter->taskStatus++;

            }

            // 4 等待取篮放行 到达人工下料工位 内外侧无篮子
            if (iter->taskStatus == 4 && currentStationInfoMap.value(iter->unload).Currentpoint == AGVCurrentTaskI.currentNode){

                // 有篮
                if (X17 || (X18 && X20))
                {
                    // 计时=0
                    if (Music_Time.toString().isEmpty())
                    {
                        Music_Time = QDateTime::currentDateTime();
                    }

                    // 超时30S，语音提醒
                    else if (Music_Time.secsTo(QDateTime::currentDateTime()) > 30)
                    {
                        // 创建设置语音任务（更换电池广播）
                        ESS_Single::GetInstance()->setAgvMusicTask(iter->agvNum.toInt(), 1);
                    }

                }

                // 空篮
                else if (!X17 && !X18 && !X19 && !X20)
                {
                    // 计时=0
                    if (OUT_Time.toString().isEmpty())
                    {
                        OUT_Time = QDateTime::currentDateTime();
                    }

                    // 黄色放行X12=1，黄色确认Y11=0
                    else if (PLC_Read(iter->unload, "X12") && !PLC_Read(iter->unload, "Y11"))
                    {
                        // 黄色确认Y11置1
                        PLC_Write(iter->unload, "RX_Y11", 1);
                    }

                    // 黄色确认Y11=1||超时60S
                    else if (PLC_Read(iter->unload, "Y11") || OUT_Time.secsTo(QDateTime::currentDateTime()) > 60)
                    {

                        // 计时情空
                        OUT_Time = nullTime;

                        Music_Time = nullTime;

                        // 下发RCS移动任务，前往清洗出料工位4
                        iter->taskId_ess = "Move-" + QString::number(iter->SAPTaskIndex) + "-4";

                        ESS_Single::GetInstance()->setMoveTask(iter.value(), currentStationInfoMap.value(iter->load).currentStation, "MOVE", 0);

                        iter->taskStatus++;

                    }else
                    {
                        //提示文本描述显示
                        emit sig_TextDisplay(tr("%1 任务条件不满足--->OUT_Time：%2 X12：%3 Y11：%4").arg(iter->SAPTaskIndex).arg(OUT_Time.secsTo(QDateTime::currentDateTime()))
                                             .arg(PLC_Read(iter->unload, "X12")).arg(PLC_Read(iter->unload, "Y11")));

                        qDebug()<<"-----任务条件不满足---->taskId:"<<iter->taskId<<" OUT_Time:"<<OUT_Time.secsTo(QDateTime::currentDateTime())
                               <<" X12:"<<PLC_Read(iter->unload, "X12")<<" Y11:"<<PLC_Read(iter->unload, "Y11");
                    }

                }

            }

            // 5 取篮放行完成

            // 6 前往清洗出料 到达清洗出料工位
            if (iter->taskStatus == 6 && currentStationInfoMap.value(iter->load).Currentpoint == AGVCurrentTaskI.currentNode){

                // 任务正常完成
                iter->taskStatus=100;

                iter->taskId_agv = iter->taskId_ess;

                // 放行RCS移动任务，前往清洗出料工位
                ESS_Single::GetInstance()->setRunActionTask(iter.value());

                // 复位 PLC 按钮盒信号
                StationStatus_Reset(iter.value());

            }

            // 防止任务完成更新状态失败
            if(iter->taskStatus == 6 && !X17 && !X18 && !X19 && !X20 && iter->taskId != AGVCurrentTaskI.taskId)
            {
                // 任务正常完成
                iter->taskStatus=100;
            }

        }

        /********************************** 任务状态变化 *********************************/
        //任务状态改变及时更新数据库
        if (iter->taskStatus!=iter->latstaskStatus){

            iter->latstaskStatus=iter->taskStatus;
            QString taskType=iter->taskType+"_"+QString::number(iter->taskStatus);
            iter->taskStatusDesc=ServerInitItem.taskStatusMap.value(taskType);
            slectSAPExcelInfoTask.insert(iter->SAPTaskIndex,iter.value());

            qDebug()<<"Update taskStatus ---->taskId:"<<iter->taskId<<" taskType:"<<iter->taskType
                   <<" taskId_ess:"<<iter->taskId_ess<<" taskStatus:"<<iter->taskStatus;
        }

        iter++;
    }

    return true;
}

bool taskManagerServer::ProcessMsgRecv()
{
    // 删除任务反馈
    if (!cancelSAPExcelInfoTask.isEmpty()){
        ReplyMsg ReplyMsgI=sapMsgInterface::getInstance()->GetMsgRecv_Msg(cancelSAPExcelInfoTask.firstKey());
        if (ReplyMsgI.keyId!=""){
            cancelSAPExcelInfoTask.remove(cancelSAPExcelInfoTask.firstKey());
            qDebug()<<"获取POST返回值 remove---->keyId:"<<ReplyMsgI.keyId;
        }
        return false;
    }

    QMap<int, SAPExcelInfo>::iterator iter=currentSAPExcelInfoTask.begin();
    while (iter!=currentSAPExcelInfoTask.end()) {
        if (iter->taskId!=nullptr){

            ReplyMsg ReplyMsgI=sapMsgInterface::getInstance()->GetMsgRecv_Msg(iter->taskId_ess);
            if (ReplyMsgI.keyId!=""){

                //当前 AGV 状态信息
                AGVCurrentTask AGVCurrentTaskI = AGVCurrentTaskMap.value(iter->agvNum);

                /******************************************* 清洗流程 RCS接收到任务****************************************/
                if (iter->taskType == "ONE"){

                    SAPExcelInfo SAPExcelInfoI;

                    // 1 开始执行任务
                    if (iter->taskStatus == 1 && ReplyMsgI.status==0){

                        iter->taskStatus++;
                    }

                    // 放行上一条任务 清洗机出料
                    if ((iter->taskStatus == 3 || iter->taskStatus == 5)
                            && ReplyMsgI.status==0 && iter->taskId_agv != iter->taskId_ess){

                        SAPExcelInfoI = iter.value();

                        SAPExcelInfoI.taskId_ess = iter->taskId_agv;

                        iter->taskId_agv = iter->taskId_ess;

                        ESS_Single::GetInstance()->setRunActionTask(SAPExcelInfoI);
                    }

                    // 放行上一条任务
                    if ((iter->taskStatus == 4 || iter->taskStatus == 6 || iter->taskStatus == 9)
                            && ReplyMsgI.status==0 && iter->taskId_agv != iter->taskId_ess){

                        SAPExcelInfoI = iter.value();

                        SAPExcelInfoI.taskId_ess = iter->taskId_agv;

                        iter->taskId_agv = iter->taskId_ess;

                        ESS_Single::GetInstance()->setRunActionTask(SAPExcelInfoI);

                        iter->taskStatus++;
                    }

                }

                /******************************************* 转运流程 RCS接收到任务****************************************/
                if (iter->taskType == "TWO"){

                    SAPExcelInfo SAPExcelInfoI;

                    // 1 开始执行任务
                    if (iter->taskStatus == 1 && ReplyMsgI.status==0){

                        iter->taskStatus++;
                    }

                    // 放行上一条任务 清洗机出料
                    if (iter->taskStatus == 3 && ReplyMsgI.status==0 && iter->taskId_agv != iter->taskId_ess){

                        SAPExcelInfoI = iter.value();

                        SAPExcelInfoI.taskId_ess = iter->taskId_agv;

                        iter->taskId_agv = iter->taskId_ess;

                        ESS_Single::GetInstance()->setRunActionTask(SAPExcelInfoI);
                    }

                    // 放行上一条任务
                    if ((iter->taskStatus == 4 || iter->taskStatus == 7)
                            && ReplyMsgI.status==0 && iter->taskId_agv != iter->taskId_ess){

                        SAPExcelInfoI = iter.value();

                        SAPExcelInfoI.taskId_ess = iter->taskId_agv;

                        iter->taskId_agv = iter->taskId_ess;

                        ESS_Single::GetInstance()->setRunActionTask(SAPExcelInfoI);

                        iter->taskStatus++;
                    }

                }

                /******************************************* 出篮流程 RCS接收到任务****************************************/
                if (iter->taskType == "THREE"){

                    SAPExcelInfo SAPExcelInfoI;

                    // 放行上一条任务 清洗机出料
                    if (iter->taskStatus == 1 && ReplyMsgI.status==0 && iter->taskId_agv != iter->taskId_ess){

                        SAPExcelInfoI = iter.value();

                        SAPExcelInfoI.taskId_ess = iter->taskId_agv;

                        iter->taskId_agv = iter->taskId_ess;

                        ESS_Single::GetInstance()->setRunActionTask(SAPExcelInfoI);
                    }

                    // 放行上一条任务
                    if ((iter->taskStatus == 2 || iter->taskStatus == 5) && ReplyMsgI.status==0 && iter->taskId_agv != iter->taskId_ess){

                        SAPExcelInfoI = iter.value();

                        SAPExcelInfoI.taskId_ess = iter->taskId_agv;

                        iter->taskId_agv = iter->taskId_ess;

                        ESS_Single::GetInstance()->setRunActionTask(SAPExcelInfoI);

                        iter->taskStatus++;
                    }

                }

                QString taskType=iter->taskType+"_"+QString::number(iter->taskStatus);
                iter->taskStatusDesc=ServerInitItem.taskStatusMap.value(taskType);
                qDebug()<<"获取POST返回值:---->SAPTaskIndex:"<<iter->SAPTaskIndex<<" taskType:"<<iter->taskType
                       <<" containerCode:"<<iter->containerCode<<" taskId_ess:"<<iter->taskId_ess<<" taskStatus:"<<iter->taskStatus
                      <<" taskStatusDesc:"<<iter->taskStatusDesc;
            }

            // 状态 100 任务完成
            if (iter->taskStatus>=taskFnish && iter->finishTimer.isNull())
            {
                iter->finishTimer=QDateTime::currentDateTime();
                slectSAPExcelInfoTask.insert(iter.key(),iter.value());

                qDebug()<<"任务完成 更新完成时间-->taskType:"<<iter->taskType
                       <<" SAPTaskIndex:"<<iter->SAPTaskIndex<<" taskStatus:" <<iter->taskStatus
                      <<iter->taskStatusDesc<<iter->finishTimer;
            }

            //及时清除缓存
            if (iter->taskStatus>=100){
                qDebug()<<"及时清除缓存"<<iter->SAPTaskIndex;
                currentSAPExcelInfoTask.remove(iter.key());
                return true;
            }

        }else {
           qDebug()<<"QMap 数组指针越界，执行失败--taskProcessTimer"<<iter.value().containerCode;
           return false;
        }
        iter++;
    }

    return true;
}


//摄像头状态逻辑
bool taskManagerServer::ProcessCodeSAPExcelInfo()
{
    if(CodeStatusMap.isEmpty()){
        CodeStatusMap=ESS_Single::GetInstance()->getCodeStatusMap();                     //获取 MES 的所有位置状态
        emit sig_CodeStatus(CodeStatusMap);//MES 主动提交暂存位以及装机位状态信息
    }else{
        QMap<int,CodeStatus>CodeStatusMap_=ESS_Single::GetInstance()->getCodeStatusMap(); //获取 MES 的所有位置状态
        foreach(CodeStatus iter,CodeStatusMap_.values()){
            if(CodeStatusMap.contains(iter.Station)){
               CodeStatusMap.find(iter.Station).value().Room=iter.Room;
               CodeStatusMap.find(iter.Station).value().Result=iter.Result;
               CodeStatusMap.find(iter.Station).value().CarCode=iter.CarCode;
               CodeStatusMap.find(iter.Station).value().CarStauts=iter.CarStauts;
               CodeStatusMap.find(iter.Station).value().Locked=iter.Locked;
               CodeStatusMap.find(iter.Station).value().WaitCheck=iter.WaitCheck;
               CodeStatusMap.find(iter.Station).value().Priority=iter.Priority;
               CodeStatusMap.find(iter.Station).value().upDateDesc=iter.upDateDesc;
               CodeStatusMap.find(iter.Station).value().statusTimer=iter.statusTimer;
            }
        }
    }
    return false;
}


bool taskManagerServer::getcurrentSAPExcelInfoTask(QString taskType)
{
    slecetSAP_Log slecetSAP_LogI;
    slecetSAP_LogI.taskType=taskType;
    if(slecetSAP_LogI.taskType == "new" && currentSAPExcelInfoTask.isEmpty()){
       slecetSAP_LogI.taskStatus_s=0;
       slecetSAP_LogI.taskStatus_e=90;
    }
    QMap<int, SAPExcelInfo> newSAPExcelInfoTask_=queryServer::getInstance()->querySAPExcelInfoList(slecetSAP_LogI);
    if(!newSAPExcelInfoTask_.isEmpty()){
        foreach(const int SAPTaskIndex,newSAPExcelInfoTask_.keys())
        {
            if(!currentSAPExcelInfoTask.contains(SAPTaskIndex)){
                SAPExcelInfo SAPExcelInfoI=newSAPExcelInfoTask_.value(SAPTaskIndex);
                slectSAPExcelInfoTask.insert(SAPExcelInfoI.SAPTaskIndex,SAPExcelInfoI);
                currentSAPExcelInfoTask.insert(SAPTaskIndex,newSAPExcelInfoTask_.value(SAPTaskIndex));
//                setSAPCodeStatus(SAPExcelInfoI); //设置工位任务绑定与解绑
            }
        }
    }
    return true;
}

void taskManagerServer::deleteTextFilesOlderThan(QString folderPath, int days)
{
    QDir folder(folderPath); // 创建一个QDir对象，表示文件夹路径
    if (!folder.exists()) // 检查文件夹是否存在
        return;

    QDateTime currentTime = QDateTime::currentDateTime(); // 获取当前日期和时间

    QString filter = "*.log"; // 文件过滤器，只匹配文本文件（以.log结尾），可以根据需求修改
    QStringList fileList = folder.entryList(QStringList(filter), QDir::Files); // 获取文件夹中的文本文件列表

    foreach (QString file, fileList) // 遍历文件列表
    {
        QString filePath = folder.filePath(file); // 构建文件完整路径
        QFileInfo fileInfo(filePath); // 创建QFileInfo对象，获取文件信息
        QDateTime fileModifiedTime = fileInfo.lastModified(); // 获取文件的最后修改时间

        int daysSinceModified = fileModifiedTime.daysTo(currentTime); // 计算文件最后修改时间与当前时间的天数间隔
        if (daysSinceModified > days) // 如果间隔超过设定的天数阈值
        {
            QFile::remove(filePath); // 删除文件
            qDebug() << "删除文件: " << filePath;
        }
    }
}

int taskManagerServer::getCurrentWorkStation(SAPExcelInfo SAPExcelInfoI)
{
    int AGVId=0;
    if(SAPExcelInfoI.loadPoint>0 && SAPExcelInfoI.unloadPoint>0){   //当取货点及卸货点均不为零时
        AGVId=getCurrentStation(SAPExcelInfoI,SAPExcelInfoI.loadPoint,SAPExcelInfoI.unloadPoint,0,SAPExcelInfoI.taskType); //获取当前小车
        if(AGVId>0 && !taskAgvNumMap.contains(SAPExcelInfoI.SAPTaskIndex)){
            taskAgvNumMap.insert(SAPExcelInfoI.SAPTaskIndex,AGVId);
        }

        /**
         * 赖俊龙
         * 插入一次 AGV 任务只能唯一一个起始位判断容器
         */
        if (AGVId>0 && !taskLoadMap.contains(SAPExcelInfoI.SAPTaskIndex) )
        {
            taskLoadMap.insert(SAPExcelInfoI.SAPTaskIndex,SAPExcelInfoI.load);
        }
    }
    return AGVId;
}


int taskManagerServer::getCurrentStation(SAPExcelInfo SAPExcelInfoI,int loadPoint,int unloadPoint,int agvId_,QString taskType)
{
    int AGVId=0;
    int unloadPointNodeId=0;
    int loadPointNodeId=ServerInitItem.currentStationMap.key(loadPoint);    //获取当前取货点
    if(unloadPoint>0){
         unloadPointNodeId=ServerInitItem.currentStationMap.key(unloadPoint);   //获取当前卸货点
    }


    //优先查找 对应站点上的 AGV
    if(AGVId==0){
        foreach(AGVCurrentTask iter,AGVCurrentTaskMap.values()){
            qint64 onLinecount = iter.onLineTimer.secsTo(QDateTime::currentDateTime());  //在线时间
            if(onLinecount>10){
                iter.isOnline=false;
            }
            if(iter.isOnline && iter.errorCode==0 && iter.batteryLevel>20 && iter.currentStation>0){
                if(!taskAgvNumMap.values().contains(iter.AGVId) && iter.AGVId!=agvId_){
                    if(iter.currentStation==loadPointNodeId || iter.currentStation==unloadPointNodeId){
                        AGVId=iter.AGVId;   //使用本台AGV
                    }
                }
            }
        }

    }

    //根据地图坐标就近原则分配小车
    if(AGVId==0){
     int allcount=100000;
        deviceI deviceItem;
        if(ServerInitItem.StationInfoMap.contains(SAPExcelInfoI.load)){
            deviceItem=ServerInitItem.StationInfoMap.find(SAPExcelInfoI.load).value();
            foreach(AGVCurrentTask iter,AGVCurrentTaskMap.values()){
                qint64 onLinecount = iter.onLineTimer.secsTo(QDateTime::currentDateTime());  //在线时间
                if(onLinecount>10){
                    iter.isOnline=false;
                }
                if(iter.isOnline && iter.errorCode==0 && iter.batteryLevel>20){
                    if(!taskAgvNumMap.values().contains(iter.AGVId) && iter.AGVId!=agvId_ && !iter.agvPosition.isEmpty()){
                        QString agvPosition=iter.agvPosition.mid(1,(iter.agvPosition.size()-2));
                        int Position_X=agvPosition.split(",").at(0).toInt();
                        int Position_Y=agvPosition.split(",").at(1).toInt();
                        int count1=1;int count2=1;int count3=1;int count4=1;
                        int abscount=qAbs(deviceItem.x01+Position_X)+qAbs(deviceItem.y01-Position_Y);
                        if(Position_X<0){
                           count1=-1;
                        }if(Position_X<0){
                            count2=-1;
                        }if(deviceItem.x01<0){
                            count3=-1;
                        }if(deviceItem.y01<0){
                            count4=-1;
                        }
                        abscount=qAbs((deviceItem.x01*count3)+(Position_X*count1))+qAbs((deviceItem.y01*count3)+(Position_Y*count2));
                        if(allcount>abscount){
                            allcount=abscount;
                            AGVId=iter.AGVId;
                            qDebug()<<"  根据地图坐标就近原则分配小车load:"<<SAPExcelInfoI.load<<" AGVId:"<<AGVId<<" agvPosition:"<<agvPosition
                                   <<" X-Y:"<<deviceItem.x01<<deviceItem.y01;
                        }
                    }
                }

            }

        }

    }


    //查找满足条件的AGV
    if(AGVId==0){
        double batteryLevel=0.0;
        foreach(AGVCurrentTask iter,AGVCurrentTaskMap.values()){
            if(iter.isOnline && iter.errorCode==0 && iter.batteryLevel>20){
                if(!taskAgvNumMap.values().contains(iter.AGVId) && iter.AGVId!=agvId_){
                    if(taskAgvNum==0){
                        if(AGVId==0){
                            AGVId=iter.AGVId;
                            batteryLevel=iter.batteryLevel;
                        }else{
                            if(iter.batteryLevel>batteryLevel){
                                AGVId=iter.AGVId;
                                batteryLevel=iter.batteryLevel;
                            }
                        }
                    }if(taskAgvNum>0 && taskAgvNum!=iter.AGVId){
                        if(AGVId==0){
                            AGVId=iter.AGVId;
                            batteryLevel=iter.batteryLevel;
                        }else{
                            if(iter.batteryLevel>batteryLevel){
                                AGVId=iter.AGVId;
                                batteryLevel=iter.batteryLevel;
                            }
                        }
                    }
                }
            }
        }
    }

    qDebug()<<"获取-->AGVId:"<<AGVId<<" loadPoint:"<<loadPoint<<"-节点:"<<loadPointNodeId
           <<" unloadPoint:"<<unloadPoint<<"-节点:"<<unloadPointNodeId<<"  agvId_:"<<agvId_;

    return AGVId;

}

bool taskManagerServer::setSAPCodeStatus(SAPExcelInfo SAPExcelInfoI)
{
    bool update=false;
    QList<CodeStatus>CodeStatusList;
    QMap<int, CodeStatus>::iterator iter=CodeStatusMap.begin();
    while (iter!=CodeStatusMap.end()) {
        if(iter.value().deviceDesc!=nullptr){
            if((iter.value().deviceDesc==SAPExcelInfoI.load) || (iter.value().deviceDesc==SAPExcelInfoI.workStation)
                    || (iter.value().deviceDesc==SAPExcelInfoI.unload)){

                if((iter.value().SAPTaskIndex==0 || iter.value().SAPTaskIndex==SAPExcelInfoI.SAPTaskIndex)
                        && SAPExcelInfoI.taskStatus>=0 && SAPExcelInfoI.taskStatus<taskTake_wait){
                    iter.value().Locked=1;                                          //锁定(0解锁  1锁定   2解锁)           有任务时 AGV会锁定
                    iter.value().SAPTaskIndex=SAPExcelInfoI.SAPTaskIndex;           //任务索引 唯一值
                    iter.value().agvNum=SAPExcelInfoI.agvNum.toInt();               //小车号
                    //往老化房送空车架
                    if(iter.value().deviceDesc==SAPExcelInfoI.workStation){
                        if(SAPExcelInfoI.taskType=="Empty" && SAPExcelInfoI.unload=="OUT-01"){
                            iter.value().Result=0;
                            iter.value().CarCode=SAPExcelInfoI.CarCode;
                            iter.value().CarStauts=SAPExcelInfoI.CarStauts;
                        }
                    }
                    CodeStatusList.append(iter.value());
                }

                //往老化房入料
                if(SAPExcelInfoI.taskType=="IN" && iter.value().deviceDesc==SAPExcelInfoI.workStation
                        && iter.value().SAPTaskIndex==SAPExcelInfoI.SAPTaskIndex
                        && SAPExcelInfoI.taskStatus==taskTake_wait){
                    iter.value().Locked=1;                                          //锁定(0解锁  1锁定   2解锁)           有任务时 AGV会锁定
                    iter.value().SAPTaskIndex=SAPExcelInfoI.SAPTaskIndex;           //任务索引 唯一值
                    iter.value().agvNum=SAPExcelInfoI.agvNum.toInt();               //小车号

                    iter.value().Result=0;
                    iter.value().CarCode=SAPExcelInfoI.CarCode;
                    iter.value().CarStauts=SAPExcelInfoI.CarStauts;
                    CodeStatusList.append(iter.value());

                }

                if(iter.value().SAPTaskIndex==SAPExcelInfoI.SAPTaskIndex && SAPExcelInfoI.taskStatus>=taskFnish){

                    iter.value().Locked=0;                                          //锁定(0解锁  1锁定   2解锁)           有任务时 AGV会锁定
                    iter.value().SAPTaskIndex=0;                                    //任务索引 唯一值
                    iter.value().agvNum=0;                                          //小车号

                    //从老化房出料或者  以及往上机位送空车架
                    if(SAPExcelInfoI.taskType=="OUT" || (SAPExcelInfoI.taskType=="Empty" && SAPExcelInfoI.load=="IN-01")){
                        if((iter.value().deviceDesc==SAPExcelInfoI.workStation)){
                            iter.value().CarCode=0;
                            iter.value().CarStauts=0;
                        }else{
                            iter.value().CarStauts=SAPExcelInfoI.CarStauts;
                        }
                    }

                    CodeStatusList.append(iter.value());

                }

            }
        }
        ++iter;
    }

    if(!CodeStatusList.isEmpty()){
        ESS_Single::GetInstance()->setCodeStatus_SAP(CodeStatusList);   //根据任务状态更新数据库库位状态
        qDebug()<<"设置工位任务绑定与解绑-->deviceDesc:"<< SAPExcelInfoI.workStation<<" CarCode:"<< SAPExcelInfoI.CarCode
               <<" CarStauts:"<< SAPExcelInfoI.CarStauts<<" taskStatus:"<< SAPExcelInfoI.taskStatus<<" SAPTaskIndex:"<< SAPExcelInfoI.SAPTaskIndex;
    }

    return update;
}

//设置工位车架锁定与解锁 Action:0 彻底初始化  1仅锁定    2仅解锁
bool taskManagerServer::setCodeStatusLock(QString deviceDesc,int SAPTaskIndex,int CarCode,int CarStauts,int Action)
{
    bool update=false;
    QList<CodeStatus>CodeStatusList;
    QMap<int, CodeStatus>::iterator iter=CodeStatusMap.begin();
    while (iter!=CodeStatusMap.end()) {
        if(iter.value().deviceDesc!=nullptr){
            if(iter.value().SAPTaskIndex==SAPTaskIndex && iter.value().deviceDesc==deviceDesc && SAPTaskIndex>0){
                if(Action==0){
                    iter.value().Locked=0;                                          //锁定(0解锁  1锁定   2解锁)           有任务时 AGV会锁定
                    iter.value().SAPTaskIndex=0;                                    //任务索引 唯一值
                    iter.value().agvNum=0;                                          //小车号
                    iter.value().CarCode=0;
                    iter.value().CarStauts=0;
                    if(iter.value().StationType=="station"){
                        iter.value().Result=0;                                          //老化结果                            老化完成后此字段会写入1，其他状态写入0
                    }
                    CodeStatusList.append(iter.value());
                }if(Action==1){
                    iter.value().Locked=1;
                    CodeStatusList.append(iter.value());
                }if(Action==2){         //到达老化房后
                    iter.value().Locked=0;
                    iter.value().SAPTaskIndex=0;
                    iter.value().agvNum=0;
                    CodeStatusList.append(iter.value());
                }
                update=true;
            }
        }
        ++iter;
    }

    if(!CodeStatusList.isEmpty()){
        ESS_Single::GetInstance()->setCodeStatus_SAP(CodeStatusList);
        qDebug()<<"设置工位车架锁定与解锁 0彻底初始化 1锁定 2仅改变车架编码与车架状态-->deviceDesc:"<< deviceDesc<<" CarCode:"<< CarCode<<" CarStauts:"<< CarStauts<<" Action:"<< Action<<" SAPTaskIndex:"<< SAPTaskIndex;
        return true;
    }
    return update;
}


int taskManagerServer::getCurrentAGVControl(int AGVId)
{
    int currentStation=0;
    foreach(AGVCurrentTask iter,AGVCurrentTaskMap.values()){
        if(iter.AGVId==AGVId && AGVId>0){
            if(ServerInitItem.currentStationMap.contains(iter.currentStation)){
                currentStation=ServerInitItem.currentStationMap.value(iter.currentStation);
                qDebug()<<"获取当前AGV 节点信息-->AGVId:"<<iter.AGVId<<" currentStation:"<<currentStation;
            }

        }
    }
    return currentStation;
}

int taskManagerServer::GetFreeAGV(QString agv1, QString agv2, QString agv3)
{
    int AGVId = 0;
    bool isok1 = false;
    bool isok2 = false;
    bool isok3 = false;
    bool isAGV1 = false;
    bool isAGV2 = false;
    bool isAGV3 = false;

    if(AGVCurrentTaskMap.contains(agv1) && AGVCurrentTaskMap.value(agv1).taskId.isEmpty() && AGVCurrentTaskMap.value(agv1).unitId.isEmpty()
            && AGVCurrentTaskMap.value(agv1).batteryLevel > 30 && AGVCurrentTaskMap.value(agv1).AGVState!=-1 && AGVCurrentTaskMap.value(agv1).AGVState!=-2
            && AGVCurrentTaskMap.value(agv1).errorCode==0 && AGVCurrentTaskMap.value(agv1).isOnline && AGVStationMap.value(agv1.toInt()) == 0
            && AGVCurrentTaskMap.value(agv1).mCurrentTaskNum == 0)
    {
        isok1 = true;// AGV没有任务
    }

    if(AGVCurrentTaskMap.contains(agv2) && AGVCurrentTaskMap.value(agv2).taskId.isEmpty() && AGVCurrentTaskMap.value(agv2).unitId.isEmpty()
            && AGVCurrentTaskMap.value(agv2).batteryLevel > 30 && AGVCurrentTaskMap.value(agv2).AGVState!=-1 && AGVCurrentTaskMap.value(agv2).AGVState!=-2
            && AGVCurrentTaskMap.value(agv2).errorCode==0 && AGVCurrentTaskMap.value(agv2).isOnline && AGVStationMap.value(agv2.toInt()) == 0
            && AGVCurrentTaskMap.value(agv2).mCurrentTaskNum == 0)
    {
        isok2 = true;// AGV没有任务
    }

    if(AGVCurrentTaskMap.contains(agv3) && AGVCurrentTaskMap.value(agv3).taskId.isEmpty() && AGVCurrentTaskMap.value(agv3).unitId.isEmpty()
            && AGVCurrentTaskMap.value(agv3).batteryLevel > 30 && AGVCurrentTaskMap.value(agv3).AGVState!=-1 && AGVCurrentTaskMap.value(agv3).AGVState!=-2
            && AGVCurrentTaskMap.value(agv3).errorCode==0 && AGVCurrentTaskMap.value(agv3).isOnline && AGVStationMap.value(agv3.toInt()) == 0
            && AGVCurrentTaskMap.value(agv3).mCurrentTaskNum == 0)
    {
        isok3 = true;// AGV没有任务
    }

    if(!isok1 && !isok2 && !isok3)
    {
        qDebug()<<" GetFreeAGV------fail------->:"<<" isok1:"<<isok1<<" isok2:"<<isok2<<" isok3:"
               <<isok3<<" isAGV1:"<<isAGV1<<" isAGV2:"<<isAGV2<<" isAGV3:"<<isAGV3;
        return AGVId;
    }

    QMap<int, SAPExcelInfo>::iterator iter=currentSAPExcelInfoTask.begin();
    while (iter!=currentSAPExcelInfoTask.end())
    {
        // 任务类型匹配
        if((iter->taskType=="UP" || iter->taskType=="DOWN" || iter->taskType=="EMPTY" ||
            iter->taskType=="WG" || iter->taskType=="JP") && iter->taskStatus>0 && iter->taskStatus<100)
        {
            if(agv1 == iter->agvNum && isok1)
            {
                isAGV1 = true;// 当前任务列表有该 AGV
                qDebug()<<" GetFreeAGV------agv1------->taskId:"<<AGVCurrentTaskMap.value(agv1).taskId<<" unitId:"<<AGVCurrentTaskMap.value(agv1).unitId;
            }

            if(agv2 == iter->agvNum && isok2)
            {
                isAGV2 = true;// 当前任务列表有该 AGV
                qDebug()<<" GetFreeAGV------agv2------->taskId:"<<AGVCurrentTaskMap.value(agv2).taskId<<" unitId:"<<AGVCurrentTaskMap.value(agv2).unitId;
            }

            if(agv3 == iter->agvNum && isok3)
            {
                isAGV3 = true;// 当前任务列表有该 AGV
                qDebug()<<" GetFreeAGV------agv3------->taskId:"<<AGVCurrentTaskMap.value(agv3).taskId<<" unitId:"<<AGVCurrentTaskMap.value(agv3).unitId;
            }
        }

        iter++;
    }

    if(isok1 && !isAGV1)
    {
        AGVId = agv1.toInt();
    }else if(isok2 && !isAGV2){
        AGVId = agv2.toInt();
    }else if(isok3 && !isAGV3){
        AGVId = agv3.toInt();
    }

    if(AGVId != 0)
    {
        qDebug()<<" GetFreeAGV------success------->taskId:"<<AGVCurrentTaskMap.value(QString::number(AGVId)).taskId
               <<" unitId:"<<AGVCurrentTaskMap.value(QString::number(AGVId)).unitId<<" AGVId:"<<AGVId
               <<" isok1:"<<isok1<<" isok2:"<<isok2<<" isok3:"<<isok3<<" isAGV1:"<<isAGV1<<" isAGV2:"<<isAGV2<<" isAGV3:"<<isAGV3;
    }

    return AGVId;
}

void taskManagerServer::returnStopStation()
{

    //空闲返回待机点判断
    QMap<QString, AGVCurrentTask>::iterator iterSTOP=AGVCurrentTaskMap.begin();
    while (iterSTOP!=AGVCurrentTaskMap.end()) {

        //4号AGV有任务清空计时
        if(iterSTOP.value().AGVId == 1 && iterSTOP.value().taskId!="" && iterSTOP.value().AGVState != 0){
            agv1Time = nullTime;//计时清空
            agv1Times=-1;
            qDebug()<<" QGStop1---clearTime-----agvId:"<<iterSTOP.value().AGVId;
        }

        //4号AGV空闲计时
        if(iterSTOP.value().AGVId == 1 && iterSTOP.value().taskId=="" && iterSTOP.value().AGVState == 0 && iterSTOP.value().currentNode != 18){
            if(agv1Time.toString().isEmpty()){
                agv1Time = QDateTime::currentDateTime();
            }
            if(!agv1Time.toString().isEmpty()){
                agv1Times = agv1Time.secsTo(QDateTime::currentDateTime());
                if(agv1Times > 5){

                    SAPExcelInfo SAPExcelInfoI;
                    SAPExcelInfoI.taskId = "STOP" + QDateTime::currentDateTime().toString("yyyyMMddhhmmss");                    //任务 ID
                    SAPExcelInfoI.taskId_ess = SAPExcelInfoI.taskId + "-1";                                                     //子任务 ID
                    SAPExcelInfoI.agvNum = QString::number(iterSTOP.value().AGVId);                                             //AGV ID

                    ESS_Single::GetInstance()->setMoveTask(SAPExcelInfoI, StopStation.value(iterSTOP.value().AGVId), "RUN");
                    agv1Time = nullTime;//计时清空
                    agv1Times=-1;
                    qDebug()<<" QGStop2----Task-----taskId:"<<iterSTOP.value().taskId<<" unitId:"<<iterSTOP.value().unitId
                           <<" station:"<<StopStation.value(iterSTOP.value().AGVId)<<" agvId:"<<iterSTOP.value().AGVId;

                }
            }
        }

        iterSTOP++;
    }
}

void taskManagerServer::UpdateStation(QString Station, int stationStatus, QString scanCode)
{
    //临时库位状态信息容器
    QMap<QString,deviceI>currentStationInfoMapI;

    //临时库位状态参数集合
    deviceI currentStationI;

    currentStationI = currentStationInfoMap.value(Station);
    currentStationI.stationStatus = stationStatus;          //站点状态 0: 无料架 1：有料架 2：满料架 3：维护中
    currentStationI.scanCode = scanCode;                    //更新工单条码
    currentStationInfoMapI.insert(Station, currentStationI);
    threadQueryI->UP_deviceI(currentStationInfoMapI);       //更新库位状态信息
}

QString taskManagerServer::GetStation(QString Station, int stationStatus, QString scanCode)
{
    QString StationI = "";

    // 回库库位
    if(Station == "HK" && scanCode.isEmpty())
    {
        if (stationStatus == 0)
        {
            if(currentStationInfoMap.value("HK1").stationStatus == stationStatus){
                StationI = "HK1";
            }else if(currentStationInfoMap.value("HK2").stationStatus == stationStatus){
                StationI = "HK2";
            }else if(currentStationInfoMap.value("HK3").stationStatus == stationStatus){
                StationI = "HK3";
            }else if(currentStationInfoMap.value("HK4").stationStatus == stationStatus){
                StationI = "HK4";
            }

        }else if (stationStatus == 1)
        {
            if(currentStationInfoMap.value("HK4").stationStatus == stationStatus){
                StationI = "HK4";
            }else if(currentStationInfoMap.value("HK3").stationStatus == stationStatus){
                StationI = "HK3";
            }else if(currentStationInfoMap.value("HK2").stationStatus == stationStatus){
                StationI = "HK2";
            }else if(currentStationInfoMap.value("HK1").stationStatus == stationStatus){
                StationI = "HK1";
            }
        }

    }

    return StationI;
}

bool taskManagerServer::PLC_Read(QString Station, QString coil)
{
    // 加锁，确保互斥访问
    QMutexLocker locker(&mutex);

    bool _coil = false;

    if(Station == "QR")
    {

        if(coil == "X10")
        {
            _coil = ModbusAllData.QR.X10;

        }else if(coil == "X11")
        {
            _coil = ModbusAllData.QR.X11;

        }else if(coil == "X12")
        {
            _coil = ModbusAllData.QR.X12;

        }else if(coil == "X13")
        {
            _coil = ModbusAllData.QR.X13;

        }else if(coil == "X14")
        {
            _coil = ModbusAllData.QR.X14;

        }else if(coil == "X15")
        {
            _coil = ModbusAllData.QR.X15;

        }else if(coil == "Y10")
        {
            _coil = ModbusAllData.QR.Y10;

        }else if(coil == "Y11")
        {
            _coil = ModbusAllData.QR.Y11;

        }else if(coil == "Y12")
        {
            _coil = ModbusAllData.QR.Y12;

        }else if(coil == "Y13")
        {
            _coil = ModbusAllData.QR.Y13;

        }else if(coil == "Y14")
        {
            _coil = ModbusAllData.QR.Y14;

        }else if(coil == "Y15")
        {
            _coil = ModbusAllData.QR.Y15;

        }else if(coil == "Connect")
        {
            _coil = ModbusAllData.QR.connectStatus;
        }

    }

    if(Station == "QC")
    {

        if(coil == "X10")
        {
            _coil = ModbusAllData.QC.X10;

        }else if(coil == "X11")
        {
            _coil = ModbusAllData.QC.X11;

        }else if(coil == "X12")
        {
            _coil = ModbusAllData.QC.X12;

        }else if(coil == "X13")
        {
            _coil = ModbusAllData.QC.X13;

        }else if(coil == "X14")
        {
            _coil = ModbusAllData.QC.X14;

        }else if(coil == "X15")
        {
            _coil = ModbusAllData.QC.X15;

        }else if(coil == "Y10")
        {
            _coil = ModbusAllData.QC.Y10;

        }else if(coil == "Y11")
        {
            _coil = ModbusAllData.QC.Y11;

        }else if(coil == "Y12")
        {
            _coil = ModbusAllData.QC.Y12;

        }else if(coil == "Y13")
        {
            _coil = ModbusAllData.QC.Y13;

        }else if(coil == "Y14")
        {
            _coil = ModbusAllData.QC.Y14;

        }else if(coil == "Y15")
        {
            _coil = ModbusAllData.QC.Y15;

        }else if(coil == "Connect")
        {
            _coil = ModbusAllData.QC.connectStatus;
        }

    }

    if(Station == "RS")
    {

        if(coil == "X10")
        {
            _coil = ModbusAllData.RS.X10;

        }else if(coil == "X11")
        {
            _coil = ModbusAllData.RS.X11;

        }else if(coil == "X12")
        {
            _coil = ModbusAllData.RS.X12;

        }else if(coil == "X13")
        {
            _coil = ModbusAllData.RS.X13;

        }else if(coil == "X14")
        {
            _coil = ModbusAllData.RS.X14;

        }else if(coil == "X15")
        {
            _coil = ModbusAllData.RS.X15;

        }else if(coil == "Y10")
        {
            _coil = ModbusAllData.RS.Y10;

        }else if(coil == "Y11")
        {
            _coil = ModbusAllData.RS.Y11;

        }else if(coil == "Y12")
        {
            _coil = ModbusAllData.RS.Y12;

        }else if(coil == "Y13")
        {
            _coil = ModbusAllData.RS.Y13;

        }else if(coil == "Y14")
        {
            _coil = ModbusAllData.RS.Y14;

        }else if(coil == "Y15")
        {
            _coil = ModbusAllData.RS.Y15;

        }else if(coil == "Connect")
        {
            _coil = ModbusAllData.RS.connectStatus;
        }

    }

    if(Station == "RX")
    {

        if(coil == "X10")
        {
            _coil = ModbusAllData.RX.X10;

        }else if(coil == "X11")
        {
            _coil = ModbusAllData.RX.X11;

        }else if(coil == "X12")
        {
            _coil = ModbusAllData.RX.X12;

        }else if(coil == "X13")
        {
            _coil = ModbusAllData.RX.X13;

        }else if(coil == "X14")
        {
            _coil = ModbusAllData.RX.X14;

        }else if(coil == "X15")
        {
            _coil = ModbusAllData.RX.X15;

        }else if(coil == "Y10")
        {
            _coil = ModbusAllData.RX.Y10;

        }else if(coil == "Y11")
        {
            _coil = ModbusAllData.RX.Y11;

        }else if(coil == "Y12")
        {
            _coil = ModbusAllData.RX.Y12;

        }else if(coil == "Y13")
        {
            _coil = ModbusAllData.RX.Y13;

        }else if(coil == "Y14")
        {
            _coil = ModbusAllData.RX.Y14;

        }else if(coil == "Y15")
        {
            _coil = ModbusAllData.RX.Y15;

        }else if(coil == "Connect")
        {
            _coil = ModbusAllData.RX.connectStatus;
        }

    }

    return _coil;
}

void taskManagerServer::PLC_Write(QString Station, QString coil, int value)
{
    // 加锁，确保互斥访问
    QMutexLocker locker(&mutex);

    if(Station == "QR")
    {
        emit sig_MoubusWriteCoil_QR(PLCWrite.value(coil), value);
    }

    else if(Station == "QC")
    {
        emit sig_MoubusWriteCoil_QC(PLCWrite.value(coil), value);
    }

    else if(Station == "RS")
    {
        emit sig_MoubusWriteCoil_RS(PLCWrite.value(coil), value);
    }

    else if(Station == "RX")
    {
        emit sig_MoubusWriteCoil_RX(PLCWrite.value(coil), value);
    }

}

void taskManagerServer::StationStatus_Reset(SAPExcelInfo seletSAPExcelInfoI)
{
    _resetSAPExcelInfoI = seletSAPExcelInfoI;

    // ONE 清洗流程
    if(seletSAPExcelInfoI.taskType == "ONE")
    {

        if (PLC_Read(seletSAPExcelInfoI.load, "Y10"))// 清洗机入料按钮盒PLC，入料使能Y10=1
        {
            // 入料使能复位
            PLC_Write(seletSAPExcelInfoI.load, "QR_Y10", 0);

        }else if (PLC_Read(seletSAPExcelInfoI.unload, "Y10"))// 清洗机出料按钮盒PLC，出料使能Y10=1
        {          
            // 出料使能复位
            PLC_Write(seletSAPExcelInfoI.unload, "QC_Y10", 0);

        }else if (PLC_Read("RS", "Y11"))// 人工上料位按钮盒PLC，黄色确认Y11=1
        {
            // 黄色确认复位
            PLC_Write("RS", "RS_Y11", 0);

        }else if (PLC_Read("RX", "Y11"))// 人工下料位按钮盒PLC，黄色确认Y11=1
        {
            // 黄色确认复位
            PLC_Write("RX", "RX_Y11", 0);

        }else if (!PLC_Read("RS", "Y11") && !PLC_Read("RX", "Y11") && !PLC_Read(seletSAPExcelInfoI.load, "Y10") && !PLC_Read(seletSAPExcelInfoI.unload, "Y10"))
        {
            SAPExcelInfo SAPExcelInfoI;
            _resetSAPExcelInfoI = SAPExcelInfoI;

            // 计时情空
            OUT_Time = nullTime;

            Music_Time = nullTime;

            // AGV 无任务
            AGVStationMap.insert(seletSAPExcelInfoI.agvNum.toInt(), 0);
        }

    }

    // TWO 转运流程
    else if(seletSAPExcelInfoI.taskType == "TWO")
    {

        if (PLC_Read("QC", "Y10"))// 清洗机出料按钮盒PLC，出料使能Y10=1
        {
            // 出料使能复位
            PLC_Write("QC", "QC_Y10", 0);

        }else if (PLC_Read(seletSAPExcelInfoI.load, "Y11"))// 人工上料位按钮盒PLC，黄色确认Y11=1
        {
            // 黄色确认复位
            PLC_Write(seletSAPExcelInfoI.load, "RS_Y11", 0);

        }else if (PLC_Read(seletSAPExcelInfoI.unload, "Y11"))// 人工下料位按钮盒PLC，黄色确认Y11=1
        {
            // 黄色确认复位
            PLC_Write(seletSAPExcelInfoI.unload, "RX_Y11", 0);

        }else if (!PLC_Read(seletSAPExcelInfoI.load, "Y11") && !PLC_Read(seletSAPExcelInfoI.unload, "Y11") && !PLC_Read("QC", "Y10"))
        {
            SAPExcelInfo SAPExcelInfoI;
            _resetSAPExcelInfoI = SAPExcelInfoI;

            // 计时情空
            OUT_Time = nullTime;

            Music_Time = nullTime;

            // AGV 无任务
            AGVStationMap.insert(seletSAPExcelInfoI.agvNum.toInt(), 0);
        }

    }

    // THREE 出篮流程
    else if(seletSAPExcelInfoI.taskType == "THREE")
    {

        if (PLC_Read(seletSAPExcelInfoI.load, "Y10"))// 清洗机出料按钮盒PLC，出料使能Y10=1
        {
            // 出料使能复位
            PLC_Write(seletSAPExcelInfoI.load, "QC_Y10", 0);

        }else if (PLC_Read(seletSAPExcelInfoI.unload, "Y11"))// 人工下料位按钮盒PLC，黄色确认Y11=1
        {
            // 黄色确认复位
            PLC_Write(seletSAPExcelInfoI.unload, "RX_Y11", 0);

        }else if (!PLC_Read(seletSAPExcelInfoI.load, "Y10") && !PLC_Read(seletSAPExcelInfoI.unload, "Y11"))
        {
            SAPExcelInfo SAPExcelInfoI;
            _resetSAPExcelInfoI = SAPExcelInfoI;

            // 计时情空
            OUT_Time = nullTime;

            Music_Time = nullTime;

            // AGV 无任务
            AGVStationMap.insert(seletSAPExcelInfoI.agvNum.toInt(), 0);
        }

    }

}

void taskManagerServer::StationTimeUpdate()
{
    /************ 1 线上料位 *************/
    if (PLC_Read("SL1", "X12"))
    {
        UpdateStation("SL1", 3, "");// 3 维护中

    }else if (PLC_Read("SL1", "X10") && !PLC_Read("SL1", "X11"))
    {
        UpdateStation("SL1", 0, "");// 0 无料架

    }else if (!PLC_Read("SL1", "X10") && !PLC_Read("SL1", "X11"))
    {
        UpdateStation("SL1", 1, "");// 1 有料架

    }else if (!PLC_Read("SL1", "X10") && PLC_Read("SL1", "X11"))
    {
        UpdateStation("SL1", 2, "");// 2 满料架
    }

    /************ 1 线测试 1位 *************/
    if (PLC_Read("CS1_1", "X12"))
    {
        UpdateStation("CS1_1", 3, "");// 3 维护中

    }else if (PLC_Read("CS1_1", "X10") && !PLC_Read("CS1_1", "X11"))
    {
        UpdateStation("CS1_1", 0, "");// 0 无料架

    }else if (!PLC_Read("CS1_1", "X10") && !PLC_Read("CS1_1", "X11"))
    {
        UpdateStation("CS1_1", 1, "");// 1 有料架

    }else if (!PLC_Read("CS1_1", "X10") && PLC_Read("CS1_1", "X11"))
    {
        UpdateStation("CS1_1", 2, "");// 2 满料架
    }

    /************ 1 线测试 2位 *************/
    if (PLC_Read("CS1_2", "X12"))
    {
        UpdateStation("CS1_2", 3, "");// 3 维护中

    }else if (PLC_Read("CS1_2", "X10") && !PLC_Read("CS1_2", "X11"))
    {
        UpdateStation("CS1_2", 0, "");// 0 无料架

    }else if (!PLC_Read("CS1_2", "X10") && !PLC_Read("CS1_2", "X11"))
    {
        UpdateStation("CS1_2", 1, "");// 1 有料架

    }else if (!PLC_Read("CS1_2", "X10") && PLC_Read("CS1_2", "X11"))
    {
        UpdateStation("CS1_2", 2, "");// 2 满料架
    }

    /************ 1 线测试 3位 *************/
    if (PLC_Read("CS1_3", "X12"))
    {
        UpdateStation("CS1_3", 3, "");// 3 维护中

    }else if (PLC_Read("CS1_3", "X10") && !PLC_Read("CS1_3", "X11"))
    {
        UpdateStation("CS1_3", 0, "");// 0 无料架

    }else if (!PLC_Read("CS1_3", "X10") && !PLC_Read("CS1_3", "X11"))
    {
        UpdateStation("CS1_3", 1, "");// 1 有料架

    }else if (!PLC_Read("CS1_3", "X10") && PLC_Read("CS1_3", "X11"))
    {
        UpdateStation("CS1_3", 2, "");// 2 满料架
    }

    /************ 包装位 *************/
    if (PLC_Read("BZ", "X12"))
    {
        UpdateStation("BZ", 3, "");// 3 维护中

    }else if (PLC_Read("BZ", "X10") && !PLC_Read("BZ", "X11"))
    {
        UpdateStation("BZ", 0, "");// 0 无料架

    }else if (!PLC_Read("BZ", "X10") && !PLC_Read("BZ", "X11"))
    {
        UpdateStation("BZ", 1, "");// 1 有料架

    }else if (!PLC_Read("BZ", "X10") && PLC_Read("BZ", "X11"))
    {
        UpdateStation("BZ", 2, "");// 2 满料架
    }

}

void taskManagerServer::TaskTimeCreate()
{
    // 发送任务判断标志位
    bool send = false;

    // 当前AGV信息列表
    QMap<QString,AGVCurrentTask>::iterator iter;
    foreach(AGVCurrentTask iter, AGVCurrentTaskMap.values())
    {

        // 任务参数
        SAPExcelInfo SAPExcelInfoI;

        // 当前取料与送料库位判断标志位
        bool flag = false;

        if (iter.AGVId == 1 && iter.isOnline && (iter.AGVState == 0 || iter.AGVState == 3) && iter.batteryLevel > 30 && AGVStationMap.value(iter.AGVId) == 0)
        {
            // 获取滚筒光栅状态
            bool X17 = ESS_Single::GetInstance()->getIOStatus(iter.inputIOStatus, 17);// AGV 外中侧光栅传感器
            bool X18 = ESS_Single::GetInstance()->getIOStatus(iter.inputIOStatus, 18);// AGV 内中侧光栅传感器
            bool X19 = ESS_Single::GetInstance()->getIOStatus(iter.inputIOStatus, 19);// AGV 外侧光栅传感器
            bool X20 = ESS_Single::GetInstance()->getIOStatus(iter.inputIOStatus, 20);// AGV 内侧光栅传感器

            /************ ONE 清洗流程  *************/
            if (currentStationInfoMap.value("RS").Currentpoint == iter.currentNode && (X17 || (X18 && X20)))// 人工上料位 AGV 有料框
            {
                // 黄色按钮X12=1,黄色确认Y11=0
                if (PLC_Read("RS", "X12") && !PLC_Read("RS", "Y11"))
                {
                    // 黄色确认Y11置1
                    PLC_Write("RS", "RS_Y11", 1);

                }

                // 黄色确认Y11=1
                else if (PLC_Read("RS", "Y11"))
                {
                    // 当前任务列表
                    QMap<int, SAPExcelInfo>::iterator it=currentSAPExcelInfoTask.begin();
                    while (it!=currentSAPExcelInfoTask.end())
                    {
                        if (it->load == "QR" && it->unload == "QC" && it->agvNum == iter.AGVId)
                        {
                            flag = true;
                        }

                        it++;
                    }

                    if (!flag && !send)
                    {
                        // 任务号
                        QString taskId = "TaskId" + QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz");

                        // 任务数据封装
                        SAPExcelInfoI = ESS_Single::GetInstance()->setSAPExcelInfo_New("ONE", "清洗流程", taskId, iter.AGVId,
                                        "QR", currentStationInfoMap.find("QR").value().currentStation,
                                        "QC", currentStationInfoMap.find("QC").value().currentStation);

                        // 把新创建的任务写进数据库
                        ON_SAPExcelInfo_new(SAPExcelInfoI);

                        // AGV有任务
                        AGVStationMap.insert(iter.AGVId, 1);

                        send = true;
                    }

                }

            }

            /************ TWO 转运流程  *************/
            else if (currentStationInfoMap.value("RS").Currentpoint == iter.currentNode && !X17 && !X18 && !X19 && !X20)// 人工上料位 AGV 无料框
            {

                // 黄色按钮X12=1,黄色确认Y11=0
                if (PLC_Read("RS", "X12") && !PLC_Read("RS", "Y11"))
                {
                    // 黄色确认Y11置1
                    PLC_Write("RS", "RS_Y11", 1);

                }

                // 黄色确认Y11=1
                else if (PLC_Read("RS", "Y11"))
                {
                    // 当前任务列表
                    QMap<int, SAPExcelInfo>::iterator it=currentSAPExcelInfoTask.begin();
                    while (it!=currentSAPExcelInfoTask.end())
                    {
                        if (it->load == "RS" && it->unload == "RX" && it->agvNum == iter.AGVId)
                        {
                            flag = true;
                        }

                        it++;
                    }

                    if (!flag && !send)
                    {
                        // 任务号
                        QString taskId = "TaskId" + QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz");

                        // 任务数据封装
                        SAPExcelInfoI = ESS_Single::GetInstance()->setSAPExcelInfo_New("TWO", "转运流程", taskId, iter.AGVId,
                                        "RS", currentStationInfoMap.find("RS").value().currentStation,
                                        "RX", currentStationInfoMap.find("RX").value().currentStation);

                        // 把新创建的任务写进数据库
                        ON_SAPExcelInfo_new(SAPExcelInfoI);

                        // AGV有任务
                        AGVStationMap.insert(iter.AGVId, 1);

                        send = true;
                    }

                }

            }

            /************ THREE 出篮流程 *************/
            else if (currentStationInfoMap.value("QC").Currentpoint == iter.currentNode && !X17 && !X18 && !X19 && !X20)// 清洗机出料 AGV 无料框
            {

                // 出料位置X10=1
                if (PLC_Read("QC", "X10"))
                {
                    // 当前任务列表
                    QMap<int, SAPExcelInfo>::iterator it=currentSAPExcelInfoTask.begin();
                    while (it!=currentSAPExcelInfoTask.end())
                    {
                        if (it->load == "QC" && it->unload == "RX" && it->agvNum == iter.AGVId)
                        {
                            flag = true;
                        }

                        it++;
                    }

                    if (!flag && !send)
                    {
                        // 任务号
                        QString taskId = "TaskId" + QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz");

                        // 任务数据封装
                        SAPExcelInfoI = ESS_Single::GetInstance()->setSAPExcelInfo_New("THREE", "出篮流程", taskId, iter.AGVId,
                                        "QC", currentStationInfoMap.find("QC").value().currentStation,
                                        "RX", currentStationInfoMap.find("RX").value().currentStation);

                        // 把新创建的任务写进数据库
                        ON_SAPExcelInfo_new(SAPExcelInfoI);

                        // AGV有任务
                        AGVStationMap.insert(iter.AGVId, 1);

                        send = true;
                    }

                }

            }

        }

    }

}

//任务管理服务定时器
void taskManagerServer::taskManagerServerTimer()
{

    TableWidgetcount++;
    if(!AGVCurrentTaskMap.isEmpty() && countbool){
       countbool=false;

       switch (TableWidgetcount%remainder)
       {
           case 0x00:
                emit sigAGVCurrentTaskMap(AGVCurrentTaskMap,BatteryLevel);       //定时更新AGV任务状态信息显示
                ESS_Single::GetInstance()->setAGVCurrentTaskMap(AGVCurrentTaskMap);
               break;
           case 0x01:
                getcurrentSAPExcelInfoTask("new");                               //定时获取数据库，待执行任务 任务状态为:0
               break;
           case 0x03:
               ESS_Single::GetInstance()->setCurrentSAPExcelInfoTask(currentSAPExcelInfoTask);//定时刷新到单例模式
               break;
           case 0x04:
               ESS_Single::GetInstance()->setStationInfoMap(currentStationInfoMap);
               break;

           default:
               break;
       }

       countbool=true;
    }
    if(TableWidgetcount>10000){TableWidgetcount=0;}

}

void taskManagerServer::taskManagerServerTimer_()
{
    TableWidgetcount_++;

    deleteTextFilesOlderThan("./log/", 30); // 自动清除过期 30 天日志文件

    if(AGVCurrentTaskMap.isEmpty()){
        allServerInit ALLServerInitItem=queryServer::getInstance()->getCurrentServerInitItem();
        ServerInitItem=ALLServerInitItem.ServerInitItem;
        CurrentServerItem=ALLServerInitItem.CurrentServerItem;
        currentStationInfoMap=ALLServerInitItem.ServerInitItem.StationInfoMap;

        /************** 基础信息缓存链表赋值 *******************/
        AGVCurrentTaskMap=CurrentServerItem.AGVCurrentTaskMap;              //当前AGV状态信息

        currentSAPExcelInfoTask=CurrentServerItem.currentSAPExcelInfoTask;  //MES run task

    }else {

        if(!slectSAPExcelInfoTask.isEmpty()){
            threadQueryI->UP_SAPExcelInfotaskCode(slectSAPExcelInfoTask);//更新任务状态信息
            slectSAPExcelInfoTask.clear();
        }else{
//            if(cancelSAPExcelInfoTask.isEmpty()){
//                emit sig_CodeStatus(CodeStatusMap);                     //MES 主动提交暂存位以及装机位状态信息
//            }
        }
        if(!cancelSAPExcelInfoTask.isEmpty()){

            SAPExcelInfo SAPExcelInfoI = cancelSAPExcelInfoTask.first();
            if ( SAPExcelInfoI.taskId != "" )
            {
                ESS_Single::GetInstance()->setCancelTask(SAPExcelInfoI);
            }
            qDebug()<<"下发给RCS 取消任务--> SAPTaskIndex:"<<cancelSAPExcelInfoTask.first().SAPTaskIndex<<" taskStatus:"<<cancelSAPExcelInfoTask.first().taskStatus;
        }

    }

    if(!AGVCurrentTaskMap.isEmpty() && serverlist.isEmpty()){
        for(int port=20001;port<20006;port++){
            HttpServer *server=new HttpServer;
            if(!server->listen(QHostAddress::Any,port)){
                qDebug()<<"启动服务器失败 taskManager port"<<port;
                //exit(-1);
            }
            if(server!=nullptr){
                HttpOnLineTimer=QDateTime::currentDateTime();
                server->ServerInitItem=ServerInitItem;
                connect(server,&HttpServer::sig_AGVStatusWidget,this,&taskManagerServer::ON_AGVStatusWidget);
                connect(server,&HttpServer::sig_SAPExcelInfo_new,this,&taskManagerServer::ON_SAPExcelInfo_new);
                connect(server,&HttpServer::sig_StationStatusUpdate,this,&taskManagerServer::ON_StationStatusUpdate);
                connect(this,&taskManagerServer::sig_AgvTaskBool,server,&HttpServer::ON_AgvTaskBool);
                serverlist.append(server);
                qDebug()<<"启动服务器成功 taskManager port"<<port;
            }
        }

    }if(!serverlist.isEmpty()){
        for(int i=0;i<serverlist.size(); i++){
            qint64 onLinecount = serverlist[i]->HttpOnLineTimer.secsTo(QDateTime::currentDateTime());  //在线时间
            if(onLinecount>16){
               HttpPort=serverlist[i]->port_;
               if(serverlist[i]->close_()){
                   HttpOnLineTimer=QDateTime::currentDateTime();
                   serverlist.removeAt(i);
                   qDebug()<<"RCS AGV状态反馈异常 关闭端口监听 关闭服务器  HttpPort:"<<HttpPort;
                   return;
               }
            }
        }

        if(HttpPort>0){
            qint64 onLinecount = HttpOnLineTimer.secsTo(QDateTime::currentDateTime());  //在线时间
            if(onLinecount>10){
                HttpServer *server=new HttpServer;
                if(!server->listen(QHostAddress::Any,HttpPort)){
                    qDebug()<<"重新 启动服务器失败 taskManager port"<<HttpPort;
                    //exit(-1);
                }
                if(server!=nullptr){
                    HttpOnLineTimer=QDateTime::currentDateTime();
                    server->ServerInitItem=ServerInitItem;
                    connect(server,&HttpServer::sig_AGVStatusWidget,this,&taskManagerServer::ON_AGVStatusWidget);
                    connect(server,&HttpServer::sig_SAPExcelInfo_new,this,&taskManagerServer::ON_SAPExcelInfo_new);
                    connect(server,&HttpServer::sig_StationStatusUpdate,this,&taskManagerServer::ON_StationStatusUpdate);
                    connect(this,&taskManagerServer::sig_AgvTaskBool,server,&HttpServer::ON_AgvTaskBool);
                    serverlist.append(server);
                    qDebug()<<"重新 启动服务器成功 taskManager port"<<HttpPort;
                    HttpPort=0;
                }
            }
        }

    }

    if(TableWidgetcount_>10000){TableWidgetcount_=0;}

}

void taskManagerServer::taskManagerServerTimer_CR3()
{
    TableWidgetcount_HR++;

    if(TableWidgetcount_HR%2==0)
    {
        ModbusAllData = ModbusManageI->getModbusAllData();// 获取所有读到的 Modbus 数据

    }else{
        ESS_Single::GetInstance()->setModbusAllData(ModbusAllData);//更新 Modbus 状态信息
    }

    if(TableWidgetcount_HR%2==0 && slectSAPExcelInfoTask.isEmpty() && cancelSAPExcelInfoTask.isEmpty())
    {
        // 提示文本描述显示 正常
        emit sig_TextDisplay("");

        taskProcessTimer();  //实时判断任务状态 及处理

    }else{
        ProcessMsgRecv();    //实时判断ESS 接口返回数据
    }

    if(TableWidgetcount_HR%2==0)
    {
        StationStatus_Reset(_resetSAPExcelInfoI);// 复位 PLC 按钮盒信号

    }else{
//        currentStationInfoMap = threadQueryI->select_StationMap();//实时查询库位状态信息
    }

    if(TableWidgetcount_HR%10==0)
    {
        // 提示文本描述显示 正常
        emit sig_TextDisplay("");

        // 任务暂停不执行
        if ( agvTaskBool )
        {
            qDebug() << "AGV 任务状态暂停，不执行任务。";

            //提示文本描述显示
            emit sig_TextDisplay(tr("AGV 任务状态暂停，不执行任务。"));

        }else
        {
            TaskTimeCreate();// 实时判断创建任务
        }

    }else{
//        StationTimeUpdate();// 实时更新工位状态
    }

    if(TableWidgetcount_HR>10000){TableWidgetcount_HR=0;}
}

void taskManagerServer::ON_SAPExcelInfo_new(SAPExcelInfo SAPExcelInfoI)
{
    newSAPExcelInfoList.clear();
    if(!newSAPExcelInfoList.contains(SAPExcelInfoI.taskId)){
        if(SAPExcelInfoI.taskId!=""){
            TableWidgetcount_=0;
            newSAPExcelInfoList.insert(SAPExcelInfoI.taskId,SAPExcelInfoI);
            if(ThreadInsertI->newSAPExcelInfoTask(newSAPExcelInfoList)){//(把创建成功的任务 存入数据库)
                qDebug()<<"taskManager new task--S->  任务类型:"<<SAPExcelInfoI.taskType<<" agvNum:"<<SAPExcelInfoI.agvNum
                       <<" workStation:"<<SAPExcelInfoI.workStation<<newSAPExcelInfoList.size();
            }
            if(SAPExcelInfoI.taskStatus>=taskFnish){
                getcurrentSAPExcelInfoTask("Fnish");
            }
        }else{
            qDebug()<<"taskManager new task--E->  任务类型:"<<SAPExcelInfoI.taskType<<" agvNum:"<<SAPExcelInfoI.agvNum
                   <<" workStation:"<<SAPExcelInfoI.workStation<<" destination:"<<newSAPExcelInfoList.size();
        }
    }

}

void taskManagerServer::ON_AGVMoveTask(QString AGVIP, QString taskType, AGVCurrentTask AGVCurrentTaskI)
{
    qDebug()<<"手动创建AGV搬运任务--->AGVIP:"<<AGVIP<<" taskType:"<<taskType;


}

void taskManagerServer::ON_AgvStateWidget(agvState agvStateItemI)
{

}

void taskManagerServer::ON_AGVStatusWidget(QMap<QString,AGVStatus>AGVStatusMap_,QMap<QString,AGVTaskStatus>AGVTaskStatusMap_)
{
    QMap<QString,AGVCurrentTask>AGVCurrentTaskMap_;        //当前AGV状态信息

    if(!boolagvState){return;}
    boolagvState=false;
    currentAgvCount=0;
    QMap<QString, AGVCurrentTask>::iterator iter=AGVCurrentTaskMap.begin();
    while(iter!=AGVCurrentTaskMap.end()){
        if(iter.key()!=nullptr){
            if(AGVStatusMap_.contains(iter.key())){

                AGVStatus AGVStatusI=AGVStatusMap_.find(iter.key()).value();
                /*********** AGV状态信息 ***********/
                iter.value().AGVId=AGVStatusI.agvId;                       // agv 编号
                iter.value().taskId=AGVStatusI.taskId;                     // 任务 ID
                iter.value().unitId=AGVStatusI.unitId;                     // 子任务 ID
                iter.value().AGVState=AGVStatusI.state;                    // AGV 状态 0：正在运行，1：空闲， 2：异常，3：正在充电
                iter.value().errorCode=AGVStatusI.errorCode;               // 故障代码（故障代码参考表）
                iter.value().alarmCode=AGVStatusI.alarmCode;               // 警告代码（警告代码参考表）
                iter.value().batteryLevel=AGVStatusI.batteryLevel;         // AGV 电量，百分比
                iter.value().currentNode=AGVStatusI.currentNode;           // AGV当前节点
                iter.value().lastNodeId=AGVStatusI.lastNodeId;             // 上次读取到的节点 刚开机是0
                iter.value().currentStation=AGVStatusI.currentStation;     // 当前站点,当前不在站点上为0
                iter.value().lastNodeStation=AGVStatusI.lastNodeStation;   // AGV上次读到的节点所属站点,上次读到的节点不在站点上为0
                iter.value().agvPosition=AGVStatusI.agvPosition;           // AGV位置信息(x,y)---(6090,20310)
                iter.value().inputIOStatus=AGVStatusI.inputIOStatus;       // 输入IO状态（32个状态位）,IO状态0未触发 1触发
                iter.value().outputIOStatus=AGVStatusI.outputIOStatus;     // 输出IO状态（32个状态位）,IO状态0未触发 1触发
                iter.value().bottomQRCode=AGVStatusI.bottomQRCode;         // 底部读取到的二维码 0 未读取到
                iter.value().topQRCode=AGVStatusI.topQRCode;               // 顶部读取到的二维码 0 未读取到
                iter.value().liftHeight=AGVStatusI.liftHeight;             // 仓储型小车顶盘高度（mm）-1 代表未初始化
                iter.value().liftAngle=AGVStatusI.liftAngle;               // 仓储型小车顶盘角度（°）-1 代表未初始化
                iter.value().mCurrentTaskNum=AGVStatusI.mCurrentTaskNum;   // 小车本地任务数量，不为 0 小车在动作

                AGVStatusI.online = 1;                                     // AGV在线

                if(AGVTaskStatusMap_.contains(iter.key())){
                    AGVTaskStatus AGVTaskStatusI=AGVTaskStatusMap_.find(iter.key()).value();

                    /*********** 任务状态信息 ***********/
                    iter.value().status=AGVTaskStatusI.status;                // 任务状态   0:未执行 1:正在运行, 2：已完成
                    iter.value().station=AGVTaskStatusI.station;              // 动作站点
                    iter.value().taskType=AGVTaskStatusI.taskType;            // 任务类型 1：移动任务 2：停车延迟任务 3：自定义动作任务
                    iter.value().action=AGVTaskStatusI.action;                // 0:装载（取货）1:卸载（送货）
                    iter.value().msg=AGVTaskStatusI.msg;                      // 任务反馈描述


                    AGVTaskStatusI.currentStation=iter.value().currentStation;
                    if(iter.value().taskId!=""){
                        if(AGVTaskStatusMap.contains(iter.value().taskId)){
                            AGVTaskStatusMap.find(iter.value().taskId).value()=AGVTaskStatusI;
                            //qDebug()<<"AGV 任务状态变更--0-->taskId:"<<AGVTaskStatusI.taskId<<" status:"<<AGVTaskStatusI.status<<" agvId:"<<AGVTaskStatusI.agvId;
                        }else{
                            AGVTaskStatusMap.insert(iter.value().taskId,AGVTaskStatusI);
                            //qDebug()<<"AGV 任务状态变更--1-->taskId:"<<AGVTaskStatusI.taskId<<" status:"<<AGVTaskStatusI.status<<" agvId:"<<AGVTaskStatusI.agvId;
                        }
                    }
                }


                if(AGVStatusI.online==0){
                    iter.value().isOnline=false;
                }else{
                    iter.value().isOnline=true;
                }

                iter.value().onLineTimer=QDateTime::currentDateTime();
                if(iter.value().isOnline && iter.value().errorCode==0 && iter.value().batteryLevel>20){
                    currentAgvCount++;
                }

            }

        }else{
            return;
        }
        ++iter;
    }

    boolagvState=true;

}

void taskManagerServer::ON_UPSAPExcelInfoTask(SAPExcelInfo seletSAPExcelInfoI)
{
    QMap<int, SAPExcelInfo> UPSAPExcelInfoTask;
    QMap<int, SAPExcelInfo>::iterator iter=currentSAPExcelInfoTask.begin();
    while(iter!=currentSAPExcelInfoTask.end()){
        if(iter.value().taskId!=nullptr){
            if(seletSAPExcelInfoI.SAPTaskIndex==iter.key()){ 
                if(iter.value().taskStatus>0 && seletSAPExcelInfoI.taskStatus==0){

                    cancelSAPExcelInfoTask.insert(iter.value().taskId_ess,iter.value());//重新执行时，把RCS 上一个任务取消

                    iter.value().taskStatus=seletSAPExcelInfoI.taskStatus;
                    QString taskType=seletSAPExcelInfoI.taskType+"_"+QString::number(seletSAPExcelInfoI.taskStatus);
                    iter.value().taskStatusDesc=ServerInitItem.taskStatusMap.value(taskType);
                    UPSAPExcelInfoTask.insert(iter.key(),iter.value());

                    qDebug()<<"手动设置任务重新执行--->SAPTaskIndex:"<<seletSAPExcelInfoI.SAPTaskIndex<<" taskType:"<<seletSAPExcelInfoI.taskType<<"taskStatus:"<<iter.value().taskStatus;
                }else{
                    if(seletSAPExcelInfoI.taskStatus!=0){
                        iter.value().taskStatus=seletSAPExcelInfoI.taskStatus;
                        QString taskType=seletSAPExcelInfoI.taskType+"_"+QString::number(seletSAPExcelInfoI.taskStatus);
                        iter.value().taskStatusDesc=ServerInitItem.taskStatusMap.value(taskType);
                        UPSAPExcelInfoTask.insert(iter.key(),iter.value());
                        qDebug()<<"手动更新任务状态--->SAPTaskIndex:"<<seletSAPExcelInfoI.SAPTaskIndex<<" taskType:"<<taskType<<"actionId:"<<iter.value().taskStatus<<""<<iter.value().taskStatusDesc;
                    }
                }
            }
        }
        ++iter;
    }

    if(!UPSAPExcelInfoTask.isEmpty()){
        threadQueryI->UP_SAPExcelInfotaskCode(UPSAPExcelInfoTask);//更新任务状态信息
    }

}

void taskManagerServer::ON_AgvTaskBool(int TaskBool)
{
     agvTaskBool=TaskBool;                                      //任务状态--:  0：启动 1：暂停
     emit sig_AgvTaskBool(agvTaskBool);                         //AGV任务启动状态
     qDebug()<<"手动更改AGV任务模式、任务状态-->agvTaskBool:"<<agvTaskBool;
}

void taskManagerServer::ON_AGVCurrentTaskAction(QString AGVIP, QString Type, int Action)
{
    if(!boolagvState){return ;}

}

void taskManagerServer::ON_deleteSAPExcelInfoTask(SAPExcelInfo seletSAPExcelInfoI)
{

    QMap<QString,shelfBinInfo>shelfBinInfoMap;
    QMap<int, SAPExcelInfo> seletSAPExcelInfoTask_;
    QMap<int, SAPExcelInfo>::iterator iter=currentSAPExcelInfoTask.begin();
    while (iter!=currentSAPExcelInfoTask.end()){
        if(iter.value().taskId!=nullptr){
            if(seletSAPExcelInfoI.SAPTaskIndex==iter.value().SAPTaskIndex){
                iter.value().taskStatus=taskFnish+1;
                QString taskType=iter.value().taskType+"_"+QString::number(iter.value().taskStatus);
                iter.value().taskStatusDesc=ServerInitItem.taskStatusMap.value(taskType);
                iter.value().taskError=1;                                                   //任务错误代码
                iter.value().errortextEdit=ServerInitItem.taskStatusMap.value("delete");    //异常原因详细信息
                seletSAPExcelInfoTask_.insert(iter.value().SAPTaskIndex,iter.value());

                //删除任务库位状态复位
                StationStatus_Reset(seletSAPExcelInfoI);

                if(iter.value().taskId_ess!=""){

//                    SAPExcelInfo SAPExcelInfoI;
//                    SAPExcelInfoI = iter.value();
//                    SAPExcelInfoI.taskId_ess = "Delete-" + QString::number(iter->SAPTaskIndex) + "-1";
//                    ESS_Single::GetInstance()->setActionTask(SAPExcelInfoI, 0, 3, "Delete");

//                    //删除任务放下料车位置是否为目标库位
//                    if(AGVCurrentTaskMap.value(iter->agvNum).lastNodeStation == currentStationInfoMap.value(seletSAPExcelInfoI.unload).currentStation)
//                    {
//                        //复位目标库位 2 有料车
//                        UpdateStation(seletSAPExcelInfoI.unload, 2, "");
//                    }

                    cancelSAPExcelInfoTask.insert(iter.value().taskId_ess,iter.value());
                }



//                if(iter.value().taskStatus>6){
//                    ESS_Single::GetInstance()->updateStationStatus(iter.value().load, ESS_Single::station_EmptyPod);
//                    ESS_Single::GetInstance()->updateStationStatus(iter.value().unload, ESS_Single::station_EmptyPod);
//                }

//                setSAPCodeStatus(iter.value()); //设置工位任务绑定与解绑

                qDebug()<<"deleteSAPExcelInfoTask --->SAPTaskIndex:"<<iter.value().SAPTaskIndex<<iter.value().containerCode;
            }
        }else{
            return;
        }
        iter++;
    }

    if(!seletSAPExcelInfoTask_.isEmpty()){
        threadQueryI->UP_cancelTaskSAP(seletSAPExcelInfoTask_);
    }if(!shelfBinInfoMap.isEmpty()){
        threadQueryI->setshelfBinInfo_Status(shelfBinInfoMap,"Bindesc");//更新库位状态信息
    }

}

void taskManagerServer::ON_WriteModbusII(int address, quint16 value)
{
    // 指定Modbus线圈写入指定值
    emit sig_MoubusWriteCoil_Client(address, value);

    qDebug()<<"----------ON_WriteModbusII---------address:"<<address<<" value:"<<value;

}

void taskManagerServer::ON_StationStatusUpdate(StationStatusUpdate StationStatusUpdateI)
{

    //外层更新库位记录写入数据库
    if(ThreadInsertI->InserStationStatusUpdate(StationStatusUpdateI))
    {

        //外层更新库位状态
        UpdateStation(StationStatusUpdateI.StationName, StationStatusUpdateI.StationStatus, StationStatusUpdateI.scanCode);

        qDebug()<<"----------ON_StationStatusUpdate----success-----StationName"<<StationStatusUpdateI.StationName
               <<" StationStatus:"<<StationStatusUpdateI.StationStatus<<" scanCode:"<<StationStatusUpdateI.scanCode;
        return;
    }

    qDebug()<<"----------ON_StationStatusUpdate----fail-----StationName"<<StationStatusUpdateI.StationName
           <<" StationStatus:"<<StationStatusUpdateI.StationStatus<<" scanCode:"<<StationStatusUpdateI.scanCode;

}

void taskManagerServer::UpdateStation_Show(QString Station, int stationStatus, QString scanCode)
{
    // 库位信息暂存
    StationStatusUpdate StationStatusUpdateI;

    StationStatusUpdateI.StationName = Station;                                                                     //库位名称
    StationStatusUpdateI.StationNameDesc = ESS_Single::GetInstance()->_StationNameDescMap.value(Station);           //库位名称描述
    StationStatusUpdateI.scanCode = scanCode;                                                                       //工单条码
    StationStatusUpdateI.StationStatus = stationStatus;                                                             //库位状态 0：无料车 1：有任务 2：有料车 3：已烤完
    StationStatusUpdateI.StationStatusDesc = ESS_Single::GetInstance()->_StationStatusDescMap.value(stationStatus); //库位状态描述
    StationStatusUpdateI.QRcode = currentStationInfoMap.value(Station).waitPoint;                                   //库位二维码值
    StationStatusUpdateI.UpdateTime = QDateTime::currentDateTime();                                                 //库位更新时间

    // 更新库位记录写入数据库
    ON_StationStatusUpdate(StationStatusUpdateI);
}




